mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 13:07:52 +00:00
Merge m-i to m-c
This commit is contained in:
commit
129c8e17d5
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 948583, first part, apparently requires a clobber. (Ideas for fixing this involve removing jsopcode.tbl, which is a bit too big to do while holding up this patch.)
|
||||
Bug 957070 requires a clobber to resolve a reference to a program class member.
|
||||
|
@ -2648,7 +2648,7 @@ Accessible::RemoveChild(Accessible* aChild)
|
||||
}
|
||||
|
||||
Accessible*
|
||||
Accessible::GetChildAt(uint32_t aIndex)
|
||||
Accessible::GetChildAt(uint32_t aIndex) const
|
||||
{
|
||||
Accessible* child = mChildren.SafeElementAt(aIndex, nullptr);
|
||||
if (!child)
|
||||
@ -2669,12 +2669,6 @@ Accessible::ChildCount() const
|
||||
return mChildren.Length();
|
||||
}
|
||||
|
||||
int32_t
|
||||
Accessible::GetIndexOf(Accessible* aChild)
|
||||
{
|
||||
return (aChild->mParent != this) ? -1 : aChild->IndexInParent();
|
||||
}
|
||||
|
||||
int32_t
|
||||
Accessible::IndexInParent() const
|
||||
{
|
||||
|
@ -389,7 +389,7 @@ public:
|
||||
/**
|
||||
* Return child accessible at the given index.
|
||||
*/
|
||||
virtual Accessible* GetChildAt(uint32_t aIndex);
|
||||
virtual Accessible* GetChildAt(uint32_t aIndex) const;
|
||||
|
||||
/**
|
||||
* Return child accessible count.
|
||||
@ -399,7 +399,8 @@ public:
|
||||
/**
|
||||
* Return index of the given child accessible.
|
||||
*/
|
||||
virtual int32_t GetIndexOf(Accessible* aChild);
|
||||
int32_t GetIndexOf(const Accessible* aChild) const
|
||||
{ return (aChild->mParent != this) ? -1 : aChild->IndexInParent(); }
|
||||
|
||||
/**
|
||||
* Return index in parent accessible.
|
||||
|
@ -1669,7 +1669,7 @@ HyperTextAccessible::RenderedToContentOffset(nsIFrame* aFrame, uint32_t aRendere
|
||||
|
||||
int32_t
|
||||
HyperTextAccessible::GetChildOffset(uint32_t aChildIndex,
|
||||
bool aInvalidateAfter)
|
||||
bool aInvalidateAfter) const
|
||||
{
|
||||
if (aChildIndex == 0) {
|
||||
if (aInvalidateAfter)
|
||||
@ -1699,7 +1699,7 @@ HyperTextAccessible::GetChildOffset(uint32_t aChildIndex,
|
||||
}
|
||||
|
||||
int32_t
|
||||
HyperTextAccessible::GetChildIndexAtOffset(uint32_t aOffset)
|
||||
HyperTextAccessible::GetChildIndexAtOffset(uint32_t aOffset) const
|
||||
{
|
||||
uint32_t lastOffset = 0;
|
||||
uint32_t offsetCount = mOffsets.Length();
|
||||
|
@ -160,10 +160,8 @@ public:
|
||||
/**
|
||||
* Return character count within the hypertext accessible.
|
||||
*/
|
||||
uint32_t CharacterCount()
|
||||
{
|
||||
return GetChildOffset(ChildCount());
|
||||
}
|
||||
uint32_t CharacterCount() const
|
||||
{ return GetChildOffset(ChildCount()); }
|
||||
|
||||
/**
|
||||
* Get a character at the given offset (don't support magic offsets).
|
||||
@ -247,7 +245,7 @@ public:
|
||||
* cached offsets for next siblings of the child
|
||||
*/
|
||||
int32_t GetChildOffset(Accessible* aChild,
|
||||
bool aInvalidateAfter = false)
|
||||
bool aInvalidateAfter = false) const
|
||||
{
|
||||
int32_t index = GetIndexOf(aChild);
|
||||
return index == -1 ? -1 : GetChildOffset(index, aInvalidateAfter);
|
||||
@ -257,21 +255,21 @@ public:
|
||||
* Return text offset for the child accessible index.
|
||||
*/
|
||||
int32_t GetChildOffset(uint32_t aChildIndex,
|
||||
bool aInvalidateAfter = false);
|
||||
bool aInvalidateAfter = false) const;
|
||||
|
||||
/**
|
||||
* Return child accessible at the given text offset.
|
||||
*
|
||||
* @param aOffset [in] the given text offset
|
||||
*/
|
||||
int32_t GetChildIndexAtOffset(uint32_t aOffset);
|
||||
int32_t GetChildIndexAtOffset(uint32_t aOffset) const;
|
||||
|
||||
/**
|
||||
* Return child accessible at the given text offset.
|
||||
*
|
||||
* @param aOffset [in] the given text offset
|
||||
*/
|
||||
Accessible* GetChildAtOffset(uint32_t aOffset)
|
||||
Accessible* GetChildAtOffset(uint32_t aOffset) const
|
||||
{
|
||||
return GetChildAt(GetChildIndexAtOffset(aOffset));
|
||||
}
|
||||
@ -518,7 +516,7 @@ private:
|
||||
/**
|
||||
* End text offsets array.
|
||||
*/
|
||||
nsTArray<uint32_t> mOffsets;
|
||||
mutable nsTArray<uint32_t> mOffsets;
|
||||
};
|
||||
|
||||
|
||||
|
@ -414,7 +414,7 @@ XULTreeAccessible::SelectAll()
|
||||
// XULTreeAccessible: Accessible implementation
|
||||
|
||||
Accessible*
|
||||
XULTreeAccessible::GetChildAt(uint32_t aIndex)
|
||||
XULTreeAccessible::GetChildAt(uint32_t aIndex) const
|
||||
{
|
||||
uint32_t childCount = Accessible::ChildCount();
|
||||
if (aIndex < childCount)
|
||||
@ -522,7 +522,7 @@ XULTreeAccessible::ContainerWidget() const
|
||||
// XULTreeAccessible: public implementation
|
||||
|
||||
Accessible*
|
||||
XULTreeAccessible::GetTreeItemAccessible(int32_t aRow)
|
||||
XULTreeAccessible::GetTreeItemAccessible(int32_t aRow) const
|
||||
{
|
||||
if (aRow < 0 || IsDefunct() || !mTreeView)
|
||||
return nullptr;
|
||||
@ -679,10 +679,11 @@ XULTreeAccessible::TreeViewChanged(nsITreeView* aView)
|
||||
// XULTreeAccessible: protected implementation
|
||||
|
||||
already_AddRefed<Accessible>
|
||||
XULTreeAccessible::CreateTreeItemAccessible(int32_t aRow)
|
||||
XULTreeAccessible::CreateTreeItemAccessible(int32_t aRow) const
|
||||
{
|
||||
nsRefPtr<Accessible> accessible =
|
||||
new XULTreeItemAccessible(mContent, mDoc, this, mTree, mTreeView, aRow);
|
||||
new XULTreeItemAccessible(mContent, mDoc, const_cast<XULTreeAccessible*>(this),
|
||||
mTree, mTreeView, aRow);
|
||||
|
||||
return accessible.forget();
|
||||
}
|
||||
|
@ -46,8 +46,8 @@ public:
|
||||
virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
|
||||
EWhichChildAtPoint aWhichChild);
|
||||
|
||||
virtual Accessible* GetChildAt(uint32_t aIndex);
|
||||
virtual uint32_t ChildCount() const;
|
||||
virtual Accessible* GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
|
||||
virtual uint32_t ChildCount() const MOZ_OVERRIDE;
|
||||
virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
|
||||
|
||||
// SelectAccessible
|
||||
@ -77,7 +77,7 @@ public:
|
||||
*
|
||||
* @param aRow [in] the given row index
|
||||
*/
|
||||
Accessible* GetTreeItemAccessible(int32_t aRow);
|
||||
Accessible* GetTreeItemAccessible(int32_t aRow) const;
|
||||
|
||||
/**
|
||||
* Invalidates the number of cached treeitem accessibles.
|
||||
@ -110,11 +110,12 @@ protected:
|
||||
/**
|
||||
* Creates tree item accessible for the given row index.
|
||||
*/
|
||||
virtual already_AddRefed<Accessible> CreateTreeItemAccessible(int32_t aRow);
|
||||
virtual already_AddRefed<Accessible>
|
||||
CreateTreeItemAccessible(int32_t aRow) const;
|
||||
|
||||
nsCOMPtr<nsITreeBoxObject> mTree;
|
||||
nsITreeView* mTreeView;
|
||||
AccessibleHashtable mAccessibleCache;
|
||||
mutable AccessibleHashtable mAccessibleCache;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -180,7 +181,7 @@ public:
|
||||
* Return cell accessible for the given column. If XUL tree accessible is not
|
||||
* accessible table then return null.
|
||||
*/
|
||||
virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn)
|
||||
virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn) const
|
||||
{ return nullptr; }
|
||||
|
||||
/**
|
||||
|
@ -237,10 +237,12 @@ XULTreeGridAccessible::NativeRole()
|
||||
// XULTreeGridAccessible: XULTreeAccessible implementation
|
||||
|
||||
already_AddRefed<Accessible>
|
||||
XULTreeGridAccessible::CreateTreeItemAccessible(int32_t aRow)
|
||||
XULTreeGridAccessible::CreateTreeItemAccessible(int32_t aRow) const
|
||||
{
|
||||
nsRefPtr<Accessible> accessible =
|
||||
new XULTreeGridRowAccessible(mContent, mDoc, this, mTree, mTreeView, aRow);
|
||||
new XULTreeGridRowAccessible(mContent, mDoc,
|
||||
const_cast<XULTreeGridAccessible*>(this),
|
||||
mTree, mTreeView, aRow);
|
||||
|
||||
return accessible.forget();
|
||||
}
|
||||
@ -345,7 +347,7 @@ XULTreeGridRowAccessible::ChildAtPoint(int32_t aX, int32_t aY,
|
||||
}
|
||||
|
||||
Accessible*
|
||||
XULTreeGridRowAccessible::GetChildAt(uint32_t aIndex)
|
||||
XULTreeGridRowAccessible::GetChildAt(uint32_t aIndex) const
|
||||
{
|
||||
if (IsDefunct())
|
||||
return nullptr;
|
||||
@ -368,7 +370,7 @@ XULTreeGridRowAccessible::ChildCount() const
|
||||
// XULTreeGridRowAccessible: XULTreeItemAccessibleBase implementation
|
||||
|
||||
Accessible*
|
||||
XULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn)
|
||||
XULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn) const
|
||||
{
|
||||
NS_PRECONDITION(aColumn, "No tree column!");
|
||||
|
||||
@ -378,8 +380,9 @@ XULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn)
|
||||
return cachedCell;
|
||||
|
||||
nsRefPtr<Accessible> cell =
|
||||
new XULTreeGridCellAccessibleWrap(mContent, mDoc, this, mTree,
|
||||
mTreeView, mRow, aColumn);
|
||||
new XULTreeGridCellAccessibleWrap(mContent, mDoc,
|
||||
const_cast<XULTreeGridRowAccessible*>(this),
|
||||
mTree, mTreeView, mRow, aColumn);
|
||||
mAccessibleCache.Put(key, cell);
|
||||
Document()->BindToDocument(cell, nullptr);
|
||||
return cell;
|
||||
|
@ -62,7 +62,8 @@ public:
|
||||
protected:
|
||||
|
||||
// XULTreeAccessible
|
||||
virtual already_AddRefed<Accessible> CreateTreeItemAccessible(int32_t aRow);
|
||||
virtual already_AddRefed<Accessible>
|
||||
CreateTreeItemAccessible(int32_t aRow) const MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
|
||||
@ -91,11 +92,11 @@ public:
|
||||
virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
|
||||
EWhichChildAtPoint aWhichChild);
|
||||
|
||||
virtual Accessible* GetChildAt(uint32_t aIndex);
|
||||
virtual uint32_t ChildCount() const;
|
||||
virtual Accessible* GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
|
||||
virtual uint32_t ChildCount() const MOZ_OVERRIDE;
|
||||
|
||||
// XULTreeItemAccessibleBase
|
||||
virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn);
|
||||
virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn) const MOZ_OVERRIDE;
|
||||
virtual void RowInvalidated(int32_t aStartColIdx, int32_t aEndColIdx);
|
||||
|
||||
protected:
|
||||
@ -104,7 +105,7 @@ protected:
|
||||
virtual void CacheChildren();
|
||||
|
||||
// XULTreeItemAccessibleBase
|
||||
AccessibleHashtable mAccessibleCache;
|
||||
mutable AccessibleHashtable mAccessibleCache;
|
||||
};
|
||||
|
||||
|
||||
|
@ -41,6 +41,8 @@ support-files =
|
||||
browser_597315_c2.html
|
||||
browser_662743_sample.html
|
||||
browser_739531_sample.html
|
||||
browser_911547_sample.html
|
||||
browser_911547_sample.html^headers^
|
||||
|
||||
#NB: the following are disabled
|
||||
# browser_464620_a.html
|
||||
@ -184,3 +186,4 @@ skip-if = os == "mac"
|
||||
[browser_625016.js]
|
||||
skip-if = os == "mac"
|
||||
|
||||
[browser_911547.js]
|
||||
|
70
browser/components/sessionstore/test/browser_911547.js
Normal file
70
browser/components/sessionstore/test/browser_911547.js
Normal file
@ -0,0 +1,70 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// This tests that session restore component does restore the right content
|
||||
// security policy with the document.
|
||||
// The policy being tested disallows inline scripts
|
||||
|
||||
function test() {
|
||||
TestRunner.run();
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
// create a tab that has a CSP
|
||||
let testURL = "http://mochi.test:8888/browser/browser/components/sessionstore/test/browser_911547_sample.html";
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab(testURL);
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
let browser = tab.linkedBrowser;
|
||||
yield waitForLoad(browser);
|
||||
|
||||
// this is a baseline to ensure CSP is active
|
||||
// attempt to inject and run a script via inline (pre-restore, allowed)
|
||||
injectInlineScript(browser,'document.getElementById("test_id").value = "fail";');
|
||||
is(browser.contentDocument.getElementById("test_id").value, "ok",
|
||||
"CSP should block the inline script that modifies test_id");
|
||||
|
||||
// attempt to click a link to a data: URI (will inherit the CSP of the
|
||||
// origin document) and navigate to the data URI in the link.
|
||||
browser.contentDocument.getElementById("test_data_link").click();
|
||||
yield waitForLoad(browser);
|
||||
|
||||
is(browser.contentDocument.getElementById("test_id2").value, "ok",
|
||||
"CSP should block the script loaded by the clicked data URI");
|
||||
|
||||
// close the tab
|
||||
gBrowser.removeTab(tab);
|
||||
|
||||
// open new tab and recover the state
|
||||
tab = ss.undoCloseTab(window, 0);
|
||||
yield waitForTabRestored(tab);
|
||||
browser = tab.linkedBrowser;
|
||||
|
||||
is(browser.contentDocument.getElementById("test_id2").value, "ok",
|
||||
"CSP should block the script loaded by the clicked data URI after restore");
|
||||
|
||||
// clean up
|
||||
gBrowser.removeTab(tab);
|
||||
}
|
||||
|
||||
function waitForLoad(aElement) {
|
||||
aElement.addEventListener("load", function onLoad() {
|
||||
aElement.removeEventListener("load", onLoad, true);
|
||||
executeSoon(next);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function waitForTabRestored(aElement) {
|
||||
aElement.addEventListener("SSTabRestored", function tabRestored(e) {
|
||||
aElement.removeEventListener("SSTabRestored", tabRestored, true);
|
||||
executeSoon(next);
|
||||
}, true);
|
||||
}
|
||||
|
||||
// injects an inline script element (with a text body)
|
||||
function injectInlineScript(browser, scriptText) {
|
||||
let scriptElt = browser.contentDocument.createElement("script");
|
||||
scriptElt.type = 'text/javascript';
|
||||
scriptElt.text = scriptText;
|
||||
browser.contentDocument.body.appendChild(scriptElt);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test 911547</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!--
|
||||
this element gets modified by an injected script;
|
||||
that script should be blocked by CSP.
|
||||
Inline scripts can modify it, but not data uris.
|
||||
-->
|
||||
<input type="text" id="test_id" value="ok">
|
||||
|
||||
<a id="test_data_link" href="data:text/html,<input type='text' id='test_id2' value='ok'/> <script>document.getElementById('test_id2').value = 'fail';</script>">Test Link</a>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1 @@
|
||||
Content-Security-Policy: script-src 'self'
|
@ -11,19 +11,9 @@ interface nsIChannel;
|
||||
interface nsIDocShell;
|
||||
interface nsIDomainPolicy;
|
||||
|
||||
[scriptable, uuid(712aa338-50a1-497b-be6f-dc3d97867c01)]
|
||||
[scriptable, uuid(3b6e408b-e774-4612-89e8-3ef303564392)]
|
||||
interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
{
|
||||
///////////////// Security Checks //////////////////
|
||||
/**
|
||||
* Checks whether the running script is allowed to access aProperty.
|
||||
*/
|
||||
[noscript] void checkPropertyAccess(in JSContextPtr aJSContext,
|
||||
in JSObjectPtr aJSObject,
|
||||
in string aClassName,
|
||||
in jsid aProperty,
|
||||
in uint32_t aAction);
|
||||
|
||||
/**
|
||||
* Check that the script currently running in context "cx" can load "uri".
|
||||
*
|
||||
|
@ -113,11 +113,6 @@ private:
|
||||
|
||||
bool SubjectIsPrivileged();
|
||||
|
||||
static bool
|
||||
CheckObjectAccess(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, JSAccessMode mode,
|
||||
JS::MutableHandle<JS::Value> vp);
|
||||
|
||||
// Decides, based on CSP, whether or not eval() and stuff can be executed.
|
||||
static bool
|
||||
ContentSecurityPolicyPermitsJSAction(JSContext *cx);
|
||||
|
@ -491,9 +491,22 @@ nsPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
rv = aStream->ReadBoolean(&inMozBrowser);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = Init(codebase, appId, inMozBrowser);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = SetCsp(csp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// need to link in the CSP context here (link in a reference to this
|
||||
// nsIPrincipal and to the URI of the protected resource).
|
||||
if (csp) {
|
||||
csp->SetRequestContext(codebase, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
SetDomain(domain);
|
||||
|
||||
return NS_OK;
|
||||
@ -519,6 +532,13 @@ nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
aStream->Write32(mAppId);
|
||||
aStream->WriteBoolean(mInMozBrowser);
|
||||
|
||||
rv = NS_WriteOptionalCompoundObject(aStream, mCSP,
|
||||
NS_GET_IID(nsIContentSecurityPolicy),
|
||||
true);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// mCodebaseImmutable and mDomainImmutable will be recomputed based
|
||||
// on the deserialized URIs in Read().
|
||||
|
||||
|
@ -412,43 +412,6 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||
return evalOK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, JSAccessMode mode,
|
||||
JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
// Get the security manager
|
||||
nsScriptSecurityManager *ssm =
|
||||
nsScriptSecurityManager::GetScriptSecurityManager();
|
||||
|
||||
NS_WARN_IF_FALSE(ssm, "Failed to get security manager service");
|
||||
if (!ssm)
|
||||
return false;
|
||||
|
||||
// Get the object being accessed. We protect these cases:
|
||||
// 1. The Function.prototype.caller property's value, which might lead
|
||||
// an attacker up a call-stack to a function or another object from
|
||||
// a different trust domain.
|
||||
// 2. A user-defined getter or setter function accessible on another
|
||||
// trust domain's window or document object.
|
||||
// vp can be a primitive, in that case, we use obj as the target
|
||||
// object.
|
||||
JSObject* target = JSVAL_IS_PRIMITIVE(vp) ? obj : JSVAL_TO_OBJECT(vp);
|
||||
|
||||
// Do the same-origin check -- this sets a JS exception if the check fails.
|
||||
// Pass the parent object's class name, as we have no class-info for it.
|
||||
nsresult rv =
|
||||
ssm->CheckPropertyAccess(cx, target, js::GetObjectClass(obj)->name, id,
|
||||
(mode & JSACC_WRITE) ?
|
||||
(int32_t)nsIXPCSecurityManager::ACCESS_SET_PROPERTY :
|
||||
(int32_t)nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return false; // Security check failed (XXX was an error reported?)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsScriptSecurityManager::JSPrincipalsSubsume(JSPrincipals *first,
|
||||
@ -457,19 +420,6 @@ nsScriptSecurityManager::JSPrincipalsSubsume(JSPrincipals *first,
|
||||
return nsJSPrincipals::get(first)->Subsumes(nsJSPrincipals::get(second));
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckPropertyAccess(JSContext* cx,
|
||||
JSObject* aJSObject,
|
||||
const char* aClassName,
|
||||
jsid aProperty,
|
||||
uint32_t aAction)
|
||||
{
|
||||
return CheckPropertyAccessImpl(aAction, nullptr, cx, aJSObject,
|
||||
nullptr, nullptr,
|
||||
aClassName, aProperty);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckSameOrigin(JSContext* cx,
|
||||
nsIURI* aTargetURI)
|
||||
@ -536,196 +486,6 @@ nsScriptSecurityManager::CheckSameOriginURI(nsIURI* aSourceURI,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptSecurityManager::CheckPropertyAccessImpl(uint32_t aAction,
|
||||
nsAXPCNativeCallContext* aCallContext,
|
||||
JSContext* cx, JSObject* aJSObject,
|
||||
nsISupports* aObj,
|
||||
nsIClassInfo* aClassInfo,
|
||||
const char* aClassName, jsid aProperty)
|
||||
{
|
||||
nsresult rv;
|
||||
JS::RootedObject jsObject(cx, aJSObject);
|
||||
JS::RootedId property(cx, aProperty);
|
||||
nsIPrincipal* subjectPrincipal = GetSubjectPrincipal(cx, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!subjectPrincipal || subjectPrincipal == mSystemPrincipal)
|
||||
// We have native code or the system principal: just allow access
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> objectPrincipal;
|
||||
|
||||
// Even though security wrappers have handled our cross-origin access policy
|
||||
// since FF4, we've still always called into this function, and have relied
|
||||
// on the CAPS policy mechanism to manually approve each cross-origin property
|
||||
// based on a whitelist in all.js. This whitelist has drifted out of sync
|
||||
// with the canonical one in AccessCheck.cpp, but it's always been more
|
||||
// permissive, so we never noticed. This machinery is going away, so for now
|
||||
// let's just skip the check for cross-origin property accesses that we know
|
||||
// we get right.
|
||||
//
|
||||
// Note that while it would be nice to just rely on aClassName here, it
|
||||
// isn't set reliably by callers. :-(
|
||||
const char *className = aClassName;
|
||||
if (!className && jsObject) {
|
||||
className = JS_GetClass(jsObject)->name;
|
||||
}
|
||||
if (className &&
|
||||
(!strcmp(className, "Window") || !strcmp(className, "Location")))
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Hold the class info data here so we don't have to go back to virtual
|
||||
// methods all the time
|
||||
ClassInfoData classInfoData(aClassInfo, aClassName);
|
||||
|
||||
// If we were called from somewhere other than XPConnect
|
||||
// (no XPC call context), assume this is a DOM class. Otherwise,
|
||||
// ask the ClassInfo.
|
||||
if (aCallContext && !classInfoData.IsDOMClass()) {
|
||||
rv = NS_ERROR_DOM_PROP_ACCESS_DENIED;
|
||||
} else {
|
||||
if (!jsObject) {
|
||||
NS_ERROR("CheckPropertyAccessImpl called without a target object or URL");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIPrincipal> principalHolder;
|
||||
objectPrincipal = doGetObjectPrincipal(jsObject);
|
||||
if (!objectPrincipal)
|
||||
rv = NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = CheckSameOriginDOMProp(subjectPrincipal, objectPrincipal,
|
||||
aAction);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
if (SubjectIsPrivileged())
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-- Security tests failed, access is denied, report error
|
||||
nsAutoString stringName;
|
||||
switch(aAction)
|
||||
{
|
||||
case nsIXPCSecurityManager::ACCESS_GET_PROPERTY:
|
||||
stringName.AssignLiteral("GetPropertyDeniedOrigins");
|
||||
break;
|
||||
case nsIXPCSecurityManager::ACCESS_SET_PROPERTY:
|
||||
stringName.AssignLiteral("SetPropertyDeniedOrigins");
|
||||
break;
|
||||
case nsIXPCSecurityManager::ACCESS_CALL_METHOD:
|
||||
stringName.AssignLiteral("CallMethodDeniedOrigins");
|
||||
}
|
||||
|
||||
// Null out objectPrincipal for now, so we don't leak information about
|
||||
// it. Whenever we can report different error strings to content and
|
||||
// the UI we can take this out again.
|
||||
objectPrincipal = nullptr;
|
||||
|
||||
NS_ConvertUTF8toUTF16 classInfoName(classInfoData.GetName());
|
||||
nsAutoCString subjectOrigin;
|
||||
nsAutoCString subjectDomain;
|
||||
if (!nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin) {
|
||||
nsCOMPtr<nsIURI> uri, domain;
|
||||
subjectPrincipal->GetURI(getter_AddRefs(uri));
|
||||
if (uri) { // Object principal might be expanded
|
||||
GetOriginFromURI(uri, subjectOrigin);
|
||||
}
|
||||
subjectPrincipal->GetDomain(getter_AddRefs(domain));
|
||||
if (domain) {
|
||||
GetOriginFromURI(domain, subjectDomain);
|
||||
}
|
||||
} else {
|
||||
subjectOrigin.AssignLiteral("the security manager");
|
||||
}
|
||||
NS_ConvertUTF8toUTF16 subjectOriginUnicode(subjectOrigin);
|
||||
NS_ConvertUTF8toUTF16 subjectDomainUnicode(subjectDomain);
|
||||
|
||||
nsAutoCString objectOrigin;
|
||||
nsAutoCString objectDomain;
|
||||
if (!nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin &&
|
||||
objectPrincipal) {
|
||||
nsCOMPtr<nsIURI> uri, domain;
|
||||
objectPrincipal->GetURI(getter_AddRefs(uri));
|
||||
if (uri) { // Object principal might be system
|
||||
GetOriginFromURI(uri, objectOrigin);
|
||||
}
|
||||
objectPrincipal->GetDomain(getter_AddRefs(domain));
|
||||
if (domain) {
|
||||
GetOriginFromURI(domain, objectDomain);
|
||||
}
|
||||
}
|
||||
NS_ConvertUTF8toUTF16 objectOriginUnicode(objectOrigin);
|
||||
NS_ConvertUTF8toUTF16 objectDomainUnicode(objectDomain);
|
||||
|
||||
nsXPIDLString errorMsg;
|
||||
const char16_t *formatStrings[] =
|
||||
{
|
||||
subjectOriginUnicode.get(),
|
||||
classInfoName.get(),
|
||||
IDToString(cx, property),
|
||||
objectOriginUnicode.get(),
|
||||
subjectDomainUnicode.get(),
|
||||
objectDomainUnicode.get()
|
||||
};
|
||||
|
||||
uint32_t length = ArrayLength(formatStrings);
|
||||
|
||||
// XXXbz Our localization system is stupid and can't handle not showing
|
||||
// some strings that get passed in. Which means that we have to get
|
||||
// our length precisely right: it has to be exactly the number of
|
||||
// strings our format string wants. This means we'll have to move
|
||||
// strings in the array as needed, sadly...
|
||||
if (nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin ||
|
||||
!objectPrincipal) {
|
||||
stringName.AppendLiteral("OnlySubject");
|
||||
length -= 3;
|
||||
} else {
|
||||
// default to a length that doesn't include the domains, then
|
||||
// increase it as needed.
|
||||
length -= 2;
|
||||
if (!subjectDomainUnicode.IsEmpty()) {
|
||||
stringName.AppendLiteral("SubjectDomain");
|
||||
length += 1;
|
||||
}
|
||||
if (!objectDomainUnicode.IsEmpty()) {
|
||||
stringName.AppendLiteral("ObjectDomain");
|
||||
length += 1;
|
||||
if (length != ArrayLength(formatStrings)) {
|
||||
// We have an object domain but not a subject domain.
|
||||
// Scoot our string over one slot. See the XXX comment
|
||||
// above for why we need to do this.
|
||||
formatStrings[length-1] = formatStrings[length];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We need to keep our existing failure rv and not override it
|
||||
// with a likely success code from the following string bundle
|
||||
// call in order to throw the correct security exception later.
|
||||
nsresult rv2 = sStrBundle->FormatStringFromName(stringName.get(),
|
||||
formatStrings,
|
||||
length,
|
||||
getter_Copies(errorMsg));
|
||||
if (NS_FAILED(rv2)) {
|
||||
// Might just be missing the string... Do our best
|
||||
errorMsg = stringName;
|
||||
}
|
||||
|
||||
SetPendingException(cx, errorMsg.get());
|
||||
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsScriptSecurityManager::CheckSameOriginPrincipal(nsIPrincipal* aSubject,
|
||||
@ -1567,21 +1327,6 @@ nsScriptSecurityManager::CanGetService(JSContext *cx,
|
||||
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CanAccess(uint32_t aAction,
|
||||
nsAXPCNativeCallContext* aCallContext,
|
||||
JSContext* cx,
|
||||
JSObject* aJSObject,
|
||||
nsISupports* aObj,
|
||||
nsIClassInfo* aClassInfo,
|
||||
jsid aPropertyName)
|
||||
{
|
||||
return CheckPropertyAccessImpl(aAction, aCallContext, cx,
|
||||
aJSObject, aObj, aClassInfo,
|
||||
nullptr, aPropertyName);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Method implementing nsIChannelEventSink //
|
||||
/////////////////////////////////////////////
|
||||
@ -1688,7 +1433,6 @@ nsresult nsScriptSecurityManager::Init()
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
static const JSSecurityCallbacks securityCallbacks = {
|
||||
CheckObjectAccess,
|
||||
ContentSecurityPolicyPermitsJSAction,
|
||||
JSPrincipalsSubsume,
|
||||
};
|
||||
|
@ -63,7 +63,6 @@ included_inclnames_to_ignore = set([
|
||||
'double-conversion.h', # strange MFBT case
|
||||
'javascript-trace.h', # generated in $OBJDIR if HAVE_DTRACE is defined
|
||||
'jsautokw.h', # generated in $OBJDIR
|
||||
'jsautooplen.h', # generated in $OBJDIR
|
||||
'jscustomallocator.h', # provided by embedders; allowed to be missing
|
||||
'js-config.h', # generated in $OBJDIR
|
||||
'pratom.h', # NSPR
|
||||
|
@ -2,11 +2,12 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsISerializable.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIChannel;
|
||||
interface nsIDocShell;
|
||||
interface nsIPrincipal;
|
||||
|
||||
/**
|
||||
* nsIContentSecurityPolicy
|
||||
@ -15,8 +16,8 @@ interface nsIDocShell;
|
||||
* one of these per document/principal.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(2e7875a3-8cb5-4ebb-905b-af0a90dae594)]
|
||||
interface nsIContentSecurityPolicy : nsISupports
|
||||
[scriptable, uuid(8b91f829-b1bf-4327-8ece-4000aa823394)]
|
||||
interface nsIContentSecurityPolicy : nsISerializable
|
||||
{
|
||||
|
||||
/**
|
||||
@ -180,10 +181,18 @@ interface nsIContentSecurityPolicy : nsISupports
|
||||
const unsigned short VIOLATION_TYPE_HASH_STYLE = 7;
|
||||
|
||||
/**
|
||||
* Called after the CSP object is created to fill in the appropriate request
|
||||
* and request header information needed in case a report needs to be sent.
|
||||
* Called after the CSP object is created to fill in appropriate request
|
||||
* context and give it a reference to its owning principal for violation
|
||||
* report generation.
|
||||
* This will use whatever data is available, choosing earlier arguments first
|
||||
* if multiple are available. Either way, it will attempt to obtain the URI,
|
||||
* referrer and the principal from whatever is available. If the channel is
|
||||
* available, it'll also store that for processing policy-uri directives.
|
||||
*/
|
||||
void scanRequestData(in nsIChannel aChannel);
|
||||
void setRequestContext(in nsIURI selfURI,
|
||||
in nsIURI referrer,
|
||||
in nsIPrincipal documentPrincipal,
|
||||
in nsIChannel aChannel);
|
||||
|
||||
/**
|
||||
* Verifies ancestry as permitted by the policy.
|
||||
|
@ -11,6 +11,10 @@
|
||||
* that ContentSecurityPolicy has to do.
|
||||
*/
|
||||
|
||||
// these identifiers are also defined in contentSecurityPolicy.manifest.
|
||||
const CSP_CLASS_ID = Components.ID("{d1680bb4-1ac0-4772-9437-1188375e44f2}");
|
||||
const CSP_CONTRACT_ID = "@mozilla.org/contentsecuritypolicy;1";
|
||||
|
||||
/* :::::::: Constants and Helpers ::::::::::::::: */
|
||||
|
||||
const Cc = Components.classes;
|
||||
@ -123,8 +127,17 @@ function ContentSecurityPolicy() {
|
||||
}
|
||||
|
||||
ContentSecurityPolicy.prototype = {
|
||||
classID: Components.ID("{d1680bb4-1ac0-4772-9437-1188375e44f2}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentSecurityPolicy]),
|
||||
classID: CSP_CLASS_ID,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentSecurityPolicy,
|
||||
Ci.nsISerializable,
|
||||
Ci.nsISupports]),
|
||||
|
||||
// Class info is required to be able to serialize
|
||||
classInfo: XPCOMUtils.generateCI({classID: CSP_CLASS_ID,
|
||||
contractID: CSP_CONTRACT_ID,
|
||||
interfaces: [Ci.nsIContentSecurityPolicy,
|
||||
Ci.nsISerializable],
|
||||
flags: Ci.nsIClassInfo.MAIN_THREAD_ONLY}),
|
||||
|
||||
get isInitialized() {
|
||||
return this._isInitialized;
|
||||
@ -343,28 +356,45 @@ ContentSecurityPolicy.prototype = {
|
||||
/**
|
||||
* Given an nsIHttpChannel, fill out the appropriate data.
|
||||
*/
|
||||
scanRequestData:
|
||||
function(aChannel) {
|
||||
if (!aChannel)
|
||||
setRequestContext:
|
||||
function(aSelfURI, aReferrerURI, aPrincipal, aChannel) {
|
||||
|
||||
// this requires either a self URI or a http channel.
|
||||
if (!aSelfURI && !aChannel)
|
||||
return;
|
||||
|
||||
// Save the docRequest for fetching a policy-uri
|
||||
this._weakDocRequest = Cu.getWeakReference(aChannel);
|
||||
if (aChannel) {
|
||||
// Save the docRequest for fetching a policy-uri
|
||||
this._weakDocRequest = Cu.getWeakReference(aChannel);
|
||||
}
|
||||
|
||||
// save the document URI (minus <fragment>) and referrer for reporting
|
||||
let uri = aChannel.URI.cloneIgnoringRef();
|
||||
let uri = aSelfURI ? aSelfURI.cloneIgnoringRef() : aChannel.URI.cloneIgnoringRef();
|
||||
try { // GetUserPass throws for some protocols without userPass
|
||||
uri.userPass = '';
|
||||
} catch (ex) {}
|
||||
this._request = uri.asciiSpec;
|
||||
this._requestOrigin = uri;
|
||||
|
||||
//store a reference to the principal, that can later be used in shouldLoad
|
||||
this._weakRequestPrincipal = Cu.getWeakReference(Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getChannelPrincipal(aChannel));
|
||||
// store a reference to the principal, that can later be used in shouldLoad
|
||||
if (aPrincipal) {
|
||||
this._weakRequestPrincipal = Cu.getWeakReference(aPrincipal);
|
||||
} else if (aChannel) {
|
||||
this._weakRequestPrincipal = Cu.getWeakReference(Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getChannelPrincipal(aChannel));
|
||||
} else {
|
||||
CSPdebug("No principal or channel for document context; violation reports may not work.");
|
||||
}
|
||||
|
||||
if (aChannel instanceof Ci.nsIHttpChannel && aChannel.referrer) {
|
||||
// pick one: referrerURI, channel's referrer, or null (first available)
|
||||
let ref = null;
|
||||
if (aReferrerURI)
|
||||
ref = aReferrerURI;
|
||||
else if (aChannel instanceof Ci.nsIHttpChannel)
|
||||
ref = aChannel.referrer;
|
||||
|
||||
if (ref) {
|
||||
let referrer = aChannel.referrer.cloneIgnoringRef();
|
||||
try { // GetUserPass throws for some protocols without userPass
|
||||
referrer.userPass = '';
|
||||
@ -383,7 +413,7 @@ ContentSecurityPolicy.prototype = {
|
||||
function csp_appendPolicy(aPolicy, selfURI, aReportOnly, aSpecCompliant) {
|
||||
#ifndef MOZ_B2G
|
||||
CSPdebug("APPENDING POLICY: " + aPolicy);
|
||||
CSPdebug(" SELF: " + selfURI.asciiSpec);
|
||||
CSPdebug(" SELF: " + (selfURI ? selfURI.asciiSpec : " null"));
|
||||
CSPdebug("CSP 1.0 COMPLIANT : " + aSpecCompliant);
|
||||
#endif
|
||||
|
||||
@ -905,6 +935,51 @@ ContentSecurityPolicy.prototype = {
|
||||
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
},
|
||||
|
||||
/* ........ nsISerializable Methods: .............. */
|
||||
|
||||
read:
|
||||
function(aStream) {
|
||||
|
||||
this._requestOrigin = aStream.readObject(true);
|
||||
this._requestOrigin.QueryInterface(Ci.nsIURI);
|
||||
|
||||
for (let pCount = aStream.read32(); pCount > 0; pCount--) {
|
||||
let polStr = aStream.readString();
|
||||
let reportOnly = aStream.readBoolean();
|
||||
let specCompliant = aStream.readBoolean();
|
||||
// don't need self info because when the policy is turned back into a
|
||||
// string, 'self' is replaced with the explicit source expression.
|
||||
this.appendPolicy(polStr, null, reportOnly, specCompliant);
|
||||
}
|
||||
|
||||
// NOTE: the document instance that's deserializing this object (via its
|
||||
// principal) should hook itself into this._principal manually. If they
|
||||
// don't, the CSP reports will likely be blocked by nsMixedContentBlocker.
|
||||
},
|
||||
|
||||
write:
|
||||
function(aStream) {
|
||||
// need to serialize the context: request origin and such. They are
|
||||
// used when sending reports. Since _request and _requestOrigin are just
|
||||
// different representations of the same thing, only save _requestOrigin
|
||||
// (an nsIURI).
|
||||
aStream.writeCompoundObject(this._requestOrigin, Ci.nsIURI, true);
|
||||
|
||||
// we can't serialize a reference to the principal that triggered this
|
||||
// instance to serialize, so when this is deserialized by the principal the
|
||||
// caller must hook it up manually by calling setRequestContext on this
|
||||
// instance with the appropriate nsIChannel.
|
||||
|
||||
// Finally, serialize all the policies.
|
||||
aStream.write32(this._policies.length);
|
||||
|
||||
for each (var policy in this._policies) {
|
||||
aStream.writeWStringZ(policy.toString());
|
||||
aStream.writeBoolean(policy._reportOnlyMode);
|
||||
aStream.writeBoolean(policy._specCompliant);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// The POST of the violation report (if it happens) should not follow
|
||||
|
@ -2691,7 +2691,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
aChannel->GetURI(getter_AddRefs(selfURI));
|
||||
|
||||
// Store the request context for violation reports
|
||||
csp->ScanRequestData(aChannel);
|
||||
csp->SetRequestContext(nullptr, nullptr, nullptr, aChannel);
|
||||
|
||||
// ----- if the doc is an app and we want a default CSP, apply it.
|
||||
if (applyAppDefaultCSP) {
|
||||
|
@ -462,7 +462,6 @@ nsFrameMessageManager::GetDelayedFrameScripts(JSContext* aCx, JS::MutableHandle<
|
||||
|
||||
JS::Rooted<JSString*> url(aCx);
|
||||
JS::Rooted<JSObject*> pair(aCx);
|
||||
JS::Rooted<JS::Value> pairVal(aCx);
|
||||
for (uint32_t i = 0; i < mPendingScripts.Length(); ++i) {
|
||||
url = JS_NewUCStringCopyN(aCx, mPendingScripts[i].get(), mPendingScripts[i].Length());
|
||||
NS_ENSURE_TRUE(url, NS_ERROR_OUT_OF_MEMORY);
|
||||
@ -473,8 +472,7 @@ nsFrameMessageManager::GetDelayedFrameScripts(JSContext* aCx, JS::MutableHandle<
|
||||
pair = JS_NewArrayObject(aCx, 2, pairElts);
|
||||
NS_ENSURE_TRUE(pair, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
pairVal = JS::ObjectValue(*pair);
|
||||
NS_ENSURE_TRUE(JS_SetElement(aCx, array, i, &pairVal),
|
||||
NS_ENSURE_TRUE(JS_SetElement(aCx, array, i, pair),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
@ -613,7 +611,7 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
||||
retval[i].Length(), &ret)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, &ret),
|
||||
NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, ret),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
// Ensure that `scanRequestData` doesn't throw with app:// URLs
|
||||
// Ensure that `setRequestContext` doesn't throw with app:// URLs
|
||||
|
||||
const csp = SpecialPowers.Cc["@mozilla.org/contentsecuritypolicy;1"]
|
||||
.createInstance(SpecialPowers.Ci.nsIContentSecurityPolicy);
|
||||
@ -44,10 +44,10 @@
|
||||
let appchan = SpecialPowers.Services.io.newChannel(gManifestURL, null, null);
|
||||
|
||||
try {
|
||||
csp.scanRequestData(appchan);
|
||||
ok(true, "scanRequestData hasn't thown");
|
||||
csp.setRequestContext(null, null, null, appchan);
|
||||
ok(true, "setRequestContext hasn't thown");
|
||||
} catch(e) {
|
||||
ok(false, "scanRequestData throws");
|
||||
ok(false, "setRequestContext throws");
|
||||
}
|
||||
|
||||
cleanup()
|
||||
|
@ -76,7 +76,7 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
|
||||
dump("Created test " + id + " : " + policy + "\n\n");
|
||||
|
||||
// make the reports seem authentic by "binding" them to a channel.
|
||||
csp.scanRequestData(selfchan);
|
||||
csp.setRequestContext(selfuri, null, null, selfchan);
|
||||
|
||||
// Load up the policy
|
||||
// set as report-only if that's the case
|
||||
|
@ -100,8 +100,7 @@ const JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
|
||||
JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0),
|
||||
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, nsXULPDGlobalObject_resolve, JS_ConvertStub,
|
||||
nsXULPDGlobalObject_finalize, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr
|
||||
nsXULPDGlobalObject_finalize, nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
|
||||
|
@ -1131,7 +1131,7 @@ this.DOMApplicationRegistry = {
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Install": {
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
Services.obs.notifyObservers(null, "webapps-download-apk", JSON.stringify(msg));
|
||||
Services.obs.notifyObservers(mm, "webapps-runtime-install", JSON.stringify(msg));
|
||||
#else
|
||||
this.doInstall(msg, mm);
|
||||
#endif
|
||||
@ -1160,7 +1160,7 @@ this.DOMApplicationRegistry = {
|
||||
break;
|
||||
case "Webapps:InstallPackage": {
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
Services.obs.notifyObservers(null, "webapps-download-apk", JSON.stringify(msg));
|
||||
Services.obs.notifyObservers(mm, "webapps-runtime-install-package", JSON.stringify(msg));
|
||||
#else
|
||||
this.doInstallPackage(msg, mm);
|
||||
#endif
|
||||
|
@ -1497,21 +1497,6 @@ NS_IMETHODIMP
|
||||
nsDOMClassInfo::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, bool *_retval)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!sSecMan) {
|
||||
NS_ERROR("No security manager!!!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Ask the security manager if it's OK to enumerate
|
||||
nsresult rv =
|
||||
sSecMan->CheckPropertyAccess(cx, obj, mData->mName, sEnumerate_id,
|
||||
nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"XOWs should have stopped us from getting here!!!");
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1585,38 +1570,6 @@ nsDOMClassInfo::Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp *fop,
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMClassInfo::CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid aId, uint32_t mode,
|
||||
jsval *vp, bool *_retval)
|
||||
{
|
||||
JS::Rooted<jsid> id(cx, aId);
|
||||
uint32_t mode_type = mode & JSACC_TYPEMASK;
|
||||
|
||||
if ((mode_type == JSACC_WATCH || mode_type == JSACC_PROTO) && sSecMan) {
|
||||
nsresult rv;
|
||||
JS::Rooted<JSObject*> real_obj(cx);
|
||||
if (wrapper) {
|
||||
real_obj = wrapper->GetJSObject();
|
||||
NS_ENSURE_STATE(real_obj);
|
||||
}
|
||||
else {
|
||||
real_obj = obj;
|
||||
}
|
||||
|
||||
rv =
|
||||
sSecMan->CheckPropertyAccess(cx, real_obj, mData->mName, id,
|
||||
nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// Let XPConnect know that the access was not granted.
|
||||
*_retval = false;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMClassInfo::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, const JS::CallArgs &args, bool *_retval)
|
||||
@ -3508,25 +3461,6 @@ nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// DOM Location helper
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocationSH::CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, uint32_t mode,
|
||||
jsval *vp, bool *_retval)
|
||||
{
|
||||
if ((mode & JSACC_TYPEMASK) == JSACC_PROTO && (mode & JSACC_WRITE)) {
|
||||
// No setting location.__proto__, ever!
|
||||
|
||||
// Let XPConnect know that the access was not granted.
|
||||
*_retval = false;
|
||||
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
return nsDOMGenericSH::CheckAccess(wrapper, cx, obj, id, mode, vp, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocationSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj)
|
||||
@ -3789,7 +3723,6 @@ const JSClass sHTMLDocumentAllClass = {
|
||||
(JSResolveOp)nsHTMLDocumentSH::DocumentAllNewResolve,
|
||||
JS_ConvertStub,
|
||||
nsHTMLDocumentSH::ReleaseDocument,
|
||||
nullptr, /* checkAccess */
|
||||
nsHTMLDocumentSH::CallToGetPropMapper
|
||||
};
|
||||
|
||||
|
@ -303,10 +303,6 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
NS_IMETHOD CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, uint32_t mode,
|
||||
JS::Value *vp, bool *_retval) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
JSObject *globalObj, JSObject **parentObj) MOZ_OVERRIDE;
|
||||
NS_IMETHODIMP AddProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
|
@ -25,7 +25,6 @@
|
||||
#define DEFAULT_SCRIPTABLE_FLAGS \
|
||||
(DOM_BASE_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_NEWRESOLVE | \
|
||||
nsIXPCScriptable::WANT_CHECKACCESS | \
|
||||
nsIXPCScriptable::WANT_PRECREATE)
|
||||
|
||||
#define DOM_DEFAULT_SCRIPTABLE_FLAGS \
|
||||
|
@ -201,7 +201,6 @@ static const DOMJSClass Class = {
|
||||
%s, /* resolve */
|
||||
JS_ConvertStub,
|
||||
%s, /* finalize */
|
||||
nullptr, /* checkAccess */
|
||||
%s, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
nullptr, /* construct */
|
||||
@ -292,7 +291,6 @@ class CGPrototypeJSClass(CGThing):
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
nullptr, /* finalize */
|
||||
nullptr, /* checkAccess */
|
||||
nullptr, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
nullptr, /* construct */
|
||||
@ -350,7 +348,6 @@ static DOMIfaceAndProtoJSClass InterfaceObjectClass = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
nullptr, /* finalize */
|
||||
nullptr, /* checkAccess */
|
||||
%s, /* call */
|
||||
%s, /* hasInstance */
|
||||
%s, /* construct */
|
||||
@ -6312,7 +6309,8 @@ if (!v.isObject()) {
|
||||
return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s.%s");
|
||||
}
|
||||
|
||||
return JS_SetProperty(cx, &v.toObject(), "%s", args[0]);""" % (attrName, self.descriptor.interface.identifier.name, attrName, forwardToAttrName))).define()
|
||||
JS::Rooted<JSObject*> targetObj(cx, &v.toObject());
|
||||
return JS_SetProperty(cx, targetObj, "%s", args[0]);""" % (attrName, self.descriptor.interface.identifier.name, attrName, forwardToAttrName))).define()
|
||||
|
||||
class CGSpecializedReplaceableSetter(CGSpecializedSetter):
|
||||
"""
|
||||
@ -11409,7 +11407,7 @@ class CallbackSetter(CallbackAccessor):
|
||||
}
|
||||
return string.Template(
|
||||
'MOZ_ASSERT(argv.length() == 1);\n'
|
||||
'if (!JS_SetProperty(cx, mCallback, "${attrName}", ${argv})) {\n'
|
||||
'if (!JS_SetProperty(cx, CallbackPreserveColor(), "${attrName}", ${argv})) {\n'
|
||||
' aRv.Throw(NS_ERROR_UNEXPECTED);\n'
|
||||
' return${errorReturn};\n'
|
||||
'}\n').substitute(replacements)
|
||||
|
@ -189,8 +189,7 @@ CameraControlImpl::Get(JSContext* aCx, uint32_t aKey, JS::Value* aValue)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
v = OBJECT_TO_JSVAL(o);
|
||||
if (!JS_SetElement(aCx, array, i, &v)) {
|
||||
if (!JS_SetElement(aCx, array, i, o)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -44,9 +44,7 @@ ParseZoomRatioItemAndAdd(JSContext* aCx, JS::Handle<JSObject*> aArray,
|
||||
d /= 100;
|
||||
#endif
|
||||
|
||||
JS::Rooted<JS::Value> v(aCx, JS_NumberValue(d));
|
||||
|
||||
if (!JS_SetElement(aCx, aArray, aIndex, &v)) {
|
||||
if (!JS_SetElement(aCx, aArray, aIndex, d)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -57,7 +55,7 @@ static nsresult
|
||||
ParseStringItemAndAdd(JSContext* aCx, JS::Handle<JSObject*> aArray,
|
||||
uint32_t aIndex, const char* aStart, char** aEnd)
|
||||
{
|
||||
JSString* s;
|
||||
JS::Rooted<JSString*> s(aCx);
|
||||
|
||||
if (*aEnd) {
|
||||
s = JS_NewStringCopyN(aCx, aStart, *aEnd - aStart);
|
||||
@ -68,8 +66,7 @@ ParseStringItemAndAdd(JSContext* aCx, JS::Handle<JSObject*> aArray,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> v(aCx, STRING_TO_JSVAL(s));
|
||||
if (!JS_SetElement(aCx, aArray, aIndex, &v)) {
|
||||
if (!JS_SetElement(aCx, aArray, aIndex, s)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -102,8 +99,7 @@ ParseDimensionItemAndAdd(JSContext* aCx, JS::Handle<JSObject*> aArray,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> v(aCx, OBJECT_TO_JSVAL(o));
|
||||
if (!JS_SetElement(aCx, aArray, aIndex, &v)) {
|
||||
if (!JS_SetElement(aCx, aArray, aIndex, o)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -398,8 +394,7 @@ DOMCameraCapabilities::GetVideoSizes(JSContext* cx, JS::MutableHandle<JS::Value>
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
v = OBJECT_TO_JSVAL(o);
|
||||
if (!JS_SetElement(cx, array, i, &v)) {
|
||||
if (!JS_SetElement(cx, array, i, o)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -181,6 +181,7 @@ ArchiveRequest::GetFilenamesResult(JSContext* aCx,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
JS::Rooted<JSString*> str(aCx);
|
||||
for (uint32_t i = 0; i < aFileList.Length(); ++i) {
|
||||
nsCOMPtr<nsIDOMFile> file = aFileList[i];
|
||||
|
||||
@ -188,12 +189,10 @@ ArchiveRequest::GetFilenamesResult(JSContext* aCx,
|
||||
rv = file->GetName(filename);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSString* str = JS_NewUCStringCopyZ(aCx, filename.get());
|
||||
str = JS_NewUCStringCopyZ(aCx, filename.get());
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
JS::Rooted<JS::Value> item(aCx, STRING_TO_JSVAL(str));
|
||||
|
||||
if (NS_FAILED(rv) || !JS_SetElement(aCx, array, i, &item)) {
|
||||
if (NS_FAILED(rv) || !JS_SetElement(aCx, array, i, str)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -246,7 +245,7 @@ ArchiveRequest::GetFilesResult(JSContext* aCx,
|
||||
nsresult rv = nsContentUtils::WrapNative(aCx, global, file,
|
||||
&NS_GET_IID(nsIDOMFile),
|
||||
&value);
|
||||
if (NS_FAILED(rv) || !JS_SetElement(aCx, array, i, &value)) {
|
||||
if (NS_FAILED(rv) || !JS_SetElement(aCx, array, i, value)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ ConvertCloneReadInfosToArrayInternal(
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
if (!JS_SetElement(aCx, array, index, &val)) {
|
||||
if (!JS_SetElement(aCx, array, index, val)) {
|
||||
NS_WARNING("Failed to set array element!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
@ -1467,7 +1467,7 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!JS_SetElement(aCx, array, index, &value)) {
|
||||
if (!JS_SetElement(aCx, array, index, value)) {
|
||||
NS_WARNING("Failed to set array element!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
@ -4947,7 +4947,7 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!JS_SetElement(aCx, array, index, &value)) {
|
||||
if (!JS_SetElement(aCx, array, index, value)) {
|
||||
NS_WARNING("Failed to set array element!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ Key::DecodeJSValInternal(const unsigned char*& aPos, const unsigned char* aEnd,
|
||||
|
||||
aTypeOffset = 0;
|
||||
|
||||
if (!JS_SetElement(aCx, array, index++, &val)) {
|
||||
if (!JS_SetElement(aCx, array, index++, val)) {
|
||||
NS_WARNING("Failed to set array element!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ KeyPath::ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!JS_SetElement(aCx, arrayObj, i, &value)) {
|
||||
if (!JS_SetElement(aCx, arrayObj, i, value)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
@ -508,7 +508,7 @@ KeyPath::ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aValue) const
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
if (!JS_SetElement(aCx, array, i, &val)) {
|
||||
if (!JS_SetElement(aCx, array, i, val)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
|
@ -546,8 +546,7 @@ MmsMessage::GetDeliveryInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aDelive
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
tmpJsVal = OBJECT_TO_JSVAL(infoJsObj);
|
||||
if (!JS_SetElement(aCx, deliveryInfo, i, &tmpJsVal)) {
|
||||
if (!JS_SetElement(aCx, deliveryInfo, i, infoJsObj)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -666,8 +665,7 @@ MmsMessage::GetAttachments(JSContext* aCx, JS::MutableHandle<JS::Value> aAttachm
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
tmpJsVal = OBJECT_TO_JSVAL(attachmentObj);
|
||||
if (!JS_SetElement(aCx, attachments, i, &tmpJsVal)) {
|
||||
if (!JS_SetElement(aCx, attachments, i, attachmentObj)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -168,10 +168,8 @@ MobileMessageCallback::NotifyMessageDeleted(bool *aDeleted, uint32_t aSize)
|
||||
|
||||
JS::Rooted<JSObject*> deleteArrayObj(cx,
|
||||
JS_NewArrayObject(cx, aSize, nullptr));
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
for (uint32_t i = 0; i < aSize; i++) {
|
||||
value.setBoolean(aDeleted[i]);
|
||||
JS_SetElement(cx, deleteArrayObj, i, &value);
|
||||
JS_SetElement(cx, deleteArrayObj, i, aDeleted[i]);
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> deleteArrayVal(cx, JS::ObjectValue(*deleteArrayObj));
|
||||
|
@ -121,8 +121,7 @@ GetParamsFromSendMmsMessageRequest(JSContext* aCx,
|
||||
JS::Rooted<JSObject*> obj(aCx,
|
||||
MmsAttachmentDataToJSObject(aCx, aRequest.attachments().ElementAt(i)));
|
||||
NS_ENSURE_TRUE(obj, false);
|
||||
JS::Rooted<JS::Value> val(aCx, JS::ObjectValue(*obj));
|
||||
if (!JS_SetElement(aCx, attachmentArray, i, &val)) {
|
||||
if (!JS_SetElement(aCx, attachmentArray, i, obj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +176,6 @@ const JSClass sNPObjectJSWrapperClass =
|
||||
(JSResolveOp)NPObjWrapper_NewResolve,
|
||||
NPObjWrapper_Convert,
|
||||
NPObjWrapper_Finalize,
|
||||
nullptr, /* checkAccess */
|
||||
NPObjWrapper_Call,
|
||||
nullptr, /* hasInstance */
|
||||
NPObjWrapper_Construct
|
||||
@ -207,7 +206,7 @@ static const JSClass sNPObjectMemberClass =
|
||||
JS_PropertyStub, JS_DeletePropertyStub,
|
||||
JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub,
|
||||
JS_ResolveStub, NPObjectMember_Convert,
|
||||
NPObjectMember_Finalize, nullptr, NPObjectMember_Call,
|
||||
NPObjectMember_Finalize, NPObjectMember_Call,
|
||||
nullptr, nullptr, NPObjectMember_Trace
|
||||
};
|
||||
|
||||
@ -776,7 +775,7 @@ nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier id,
|
||||
|
||||
// static
|
||||
bool
|
||||
nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier id,
|
||||
nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier npid,
|
||||
const NPVariant *value)
|
||||
{
|
||||
NPP npp = NPPStack::Peek();
|
||||
@ -799,13 +798,15 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier id,
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(cx);
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
JSAutoCompartment ac(cx, npjsobj->mJSObj);
|
||||
JS::Rooted<JSObject*> jsObj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, jsObj);
|
||||
|
||||
JS::Rooted<JS::Value> v(cx, NPVariantToJSVal(npp, cx, value));
|
||||
|
||||
NS_ASSERTION(NPIdentifierIsInt(id) || NPIdentifierIsString(id),
|
||||
NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid),
|
||||
"id must be either string or int!\n");
|
||||
ok = ::JS_SetPropertyById(cx, npjsobj->mJSObj, NPIdentifierToJSId(id), v);
|
||||
JS::Rooted<jsid> id(cx, NPIdentifierToJSId(npid));
|
||||
ok = ::JS_SetPropertyById(cx, jsObj, id, v);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
@ -22,13 +22,6 @@
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.ignoreAllUncaughtExceptions();
|
||||
|
||||
const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
|
||||
const isOSXMtnLion = navigator.userAgent.indexOf("Mac OS X 10.8") != -1;
|
||||
if (isOSXLion || isOSXMtnLion) {
|
||||
todo(false, "Can't test plugin crash notification on OS X 10.7 or 10.8, see bug 705047");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
|
@ -150,7 +150,7 @@ ConnectWorkerToNetd::RunTask(JSContext *aCx)
|
||||
// communication.
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
|
||||
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
|
||||
JSObject *workerGlobal = JS::CurrentGlobalOrNull(aCx);
|
||||
JS::Rooted<JSObject*> workerGlobal(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
return !!JS_DefineFunction(aCx, workerGlobal, "postNetdCommand",
|
||||
DoNetdCommand, 1, 0);
|
||||
}
|
||||
|
@ -767,7 +767,6 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
|
||||
|
||||
// Security policy:
|
||||
static JSSecurityCallbacks securityCallbacks = {
|
||||
nullptr,
|
||||
ContentSecurityPolicyAllows
|
||||
};
|
||||
JS_SetSecurityCallbacks(aRuntime, &securityCallbacks);
|
||||
|
@ -55,9 +55,6 @@ public:
|
||||
void Destroy();
|
||||
nsIPrincipal* GetPrincipal();
|
||||
|
||||
static bool doCheckAccess(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, uint32_t accessType);
|
||||
|
||||
void ClearGlobalObjectOwner();
|
||||
|
||||
static const JSClass gSharedGlobalClass;
|
||||
@ -70,65 +67,6 @@ protected:
|
||||
bool mDestroyed; // Probably not necessary, but let's be safe.
|
||||
};
|
||||
|
||||
bool
|
||||
nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, uint32_t accessType)
|
||||
{
|
||||
nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
|
||||
if (!ssm) {
|
||||
::JS_ReportError(cx, "Unable to verify access to a global object property.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure to actually operate on our object, and not some object further
|
||||
// down on the proto chain.
|
||||
JS::Rooted<JSObject*> base(cx, obj);
|
||||
while (JS_GetClass(base) != &nsXBLDocGlobalObject::gSharedGlobalClass) {
|
||||
if (!::JS_GetPrototype(cx, base, &base)) {
|
||||
return false;
|
||||
}
|
||||
if (!base) {
|
||||
::JS_ReportError(cx, "Invalid access to a global object property.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = ssm->CheckPropertyAccess(cx, base, JS_GetClass(base)->name,
|
||||
id, accessType);
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
static bool
|
||||
nsXBLDocGlobalObject_getProperty(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
return nsXBLDocGlobalObject::
|
||||
doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
|
||||
}
|
||||
|
||||
static bool
|
||||
nsXBLDocGlobalObject_setProperty(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
return nsXBLDocGlobalObject::
|
||||
doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
|
||||
}
|
||||
|
||||
static bool
|
||||
nsXBLDocGlobalObject_checkAccess(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JSAccessMode mode, JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
uint32_t translated;
|
||||
if (mode & JSACC_WRITE) {
|
||||
translated = nsIXPCSecurityManager::ACCESS_SET_PROPERTY;
|
||||
} else {
|
||||
translated = nsIXPCSecurityManager::ACCESS_GET_PROPERTY;
|
||||
}
|
||||
|
||||
return nsXBLDocGlobalObject::
|
||||
doCheckAccess(cx, obj, id, translated);
|
||||
}
|
||||
|
||||
static void
|
||||
nsXBLDocGlobalObject_finalize(JSFreeOp *fop, JSObject *obj)
|
||||
{
|
||||
@ -156,11 +94,10 @@ const JSClass nsXBLDocGlobalObject::gSharedGlobalClass = {
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
|
||||
JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0),
|
||||
JS_PropertyStub, JS_DeletePropertyStub,
|
||||
nsXBLDocGlobalObject_getProperty, nsXBLDocGlobalObject_setProperty,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, nsXBLDocGlobalObject_resolve,
|
||||
JS_ConvertStub, nsXBLDocGlobalObject_finalize,
|
||||
nsXBLDocGlobalObject_checkAccess, nullptr, nullptr, nullptr,
|
||||
nullptr
|
||||
nullptr, nullptr, nullptr, nullptr
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -172,13 +172,11 @@ nsXBLProtoImpl::InitTargetObjects(nsXBLPrototypeBinding* aBinding,
|
||||
JS::Rooted<JSObject*> global(cx, sgo->GetGlobalJSObject());
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
|
||||
{
|
||||
JSAutoCompartment ac(cx, global);
|
||||
// Make sure the interface object is created before the prototype object
|
||||
// so that XULElement is hidden from content. See bug 909340.
|
||||
bool defineOnGlobal = dom::XULElementBinding::ConstructorEnabled(cx, global);
|
||||
dom::XULElementBinding::GetConstructorObject(cx, global, defineOnGlobal);
|
||||
}
|
||||
JSAutoCompartment ac(cx, global);
|
||||
// Make sure the interface object is created before the prototype object
|
||||
// so that XULElement is hidden from content. See bug 909340.
|
||||
bool defineOnGlobal = dom::XULElementBinding::ConstructorEnabled(cx, global);
|
||||
dom::XULElementBinding::GetConstructorObject(cx, global, defineOnGlobal);
|
||||
|
||||
rv = nsContentUtils::WrapNative(cx, global, aBoundElement, &v);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -287,6 +287,89 @@ public:
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Matrix4x4& o) const
|
||||
{
|
||||
// XXX would be nice to memcmp here, but that breaks IEEE 754 semantics
|
||||
return _11 == o._11 && _12 == o._12 && _13 == o._13 && _14 == o._14 &&
|
||||
_21 == o._21 && _22 == o._22 && _23 == o._23 && _24 == o._24 &&
|
||||
_31 == o._31 && _32 == o._32 && _33 == o._33 && _34 == o._34 &&
|
||||
_41 == o._41 && _42 == o._42 && _43 == o._43 && _44 == o._44;
|
||||
}
|
||||
|
||||
bool operator!=(const Matrix4x4& o) const
|
||||
{
|
||||
return !((*this) == o);
|
||||
}
|
||||
|
||||
Matrix4x4 operator*(const Matrix4x4 &aMatrix) const
|
||||
{
|
||||
Matrix4x4 matrix;
|
||||
|
||||
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21 + _13 * aMatrix._31 + _14 * aMatrix._41;
|
||||
matrix._21 = _21 * aMatrix._11 + _22 * aMatrix._21 + _23 * aMatrix._31 + _24 * aMatrix._41;
|
||||
matrix._31 = _31 * aMatrix._11 + _32 * aMatrix._21 + _33 * aMatrix._31 + _34 * aMatrix._41;
|
||||
matrix._41 = _41 * aMatrix._11 + _42 * aMatrix._21 + _43 * aMatrix._31 + _44 * aMatrix._41;
|
||||
matrix._12 = _11 * aMatrix._12 + _12 * aMatrix._22 + _13 * aMatrix._32 + _14 * aMatrix._42;
|
||||
matrix._22 = _21 * aMatrix._12 + _22 * aMatrix._22 + _23 * aMatrix._32 + _24 * aMatrix._42;
|
||||
matrix._32 = _31 * aMatrix._12 + _32 * aMatrix._22 + _33 * aMatrix._32 + _34 * aMatrix._42;
|
||||
matrix._42 = _41 * aMatrix._12 + _42 * aMatrix._22 + _43 * aMatrix._32 + _44 * aMatrix._42;
|
||||
matrix._13 = _11 * aMatrix._13 + _12 * aMatrix._23 + _13 * aMatrix._33 + _14 * aMatrix._43;
|
||||
matrix._23 = _21 * aMatrix._13 + _22 * aMatrix._23 + _23 * aMatrix._33 + _24 * aMatrix._43;
|
||||
matrix._33 = _31 * aMatrix._13 + _32 * aMatrix._23 + _33 * aMatrix._33 + _34 * aMatrix._43;
|
||||
matrix._43 = _41 * aMatrix._13 + _42 * aMatrix._23 + _43 * aMatrix._33 + _44 * aMatrix._43;
|
||||
matrix._14 = _11 * aMatrix._14 + _12 * aMatrix._24 + _13 * aMatrix._34 + _14 * aMatrix._44;
|
||||
matrix._24 = _21 * aMatrix._14 + _22 * aMatrix._24 + _23 * aMatrix._34 + _24 * aMatrix._44;
|
||||
matrix._34 = _31 * aMatrix._14 + _32 * aMatrix._24 + _33 * aMatrix._34 + _34 * aMatrix._44;
|
||||
matrix._44 = _41 * aMatrix._14 + _42 * aMatrix._24 + _43 * aMatrix._34 + _44 * aMatrix._44;
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
|
||||
/* Returns true if the matrix is an identity matrix.
|
||||
*/
|
||||
bool IsIdentity() const
|
||||
{
|
||||
return _11 == 1.0f && _12 == 0.0f && _13 == 0.0f && _14 == 0.0f &&
|
||||
_21 == 0.0f && _22 == 1.0f && _23 == 0.0f && _24 == 0.0f &&
|
||||
_31 == 0.0f && _32 == 0.0f && _33 == 1.0f && _34 == 0.0f &&
|
||||
_41 == 0.0f && _42 == 0.0f && _43 == 0.0f && _44 == 1.0f;
|
||||
}
|
||||
|
||||
bool IsSingular() const
|
||||
{
|
||||
return Determinant() == 0.0;
|
||||
}
|
||||
|
||||
Float Determinant() const
|
||||
{
|
||||
return _14 * _23 * _32 * _41
|
||||
- _13 * _24 * _32 * _41
|
||||
- _14 * _22 * _33 * _41
|
||||
+ _12 * _24 * _33 * _41
|
||||
+ _13 * _22 * _34 * _41
|
||||
- _12 * _23 * _34 * _41
|
||||
- _14 * _23 * _31 * _42
|
||||
+ _13 * _24 * _31 * _42
|
||||
+ _14 * _21 * _33 * _42
|
||||
- _11 * _24 * _33 * _42
|
||||
- _13 * _21 * _34 * _42
|
||||
+ _11 * _23 * _34 * _42
|
||||
+ _14 * _22 * _31 * _43
|
||||
- _12 * _24 * _31 * _43
|
||||
- _14 * _21 * _32 * _43
|
||||
+ _11 * _24 * _32 * _43
|
||||
+ _12 * _21 * _34 * _43
|
||||
- _11 * _22 * _34 * _43
|
||||
- _13 * _22 * _31 * _44
|
||||
+ _12 * _23 * _31 * _44
|
||||
+ _13 * _21 * _32 * _44
|
||||
- _11 * _23 * _32 * _44
|
||||
- _12 * _21 * _33 * _44
|
||||
+ _11 * _22 * _33 * _44;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Matrix5x4
|
||||
|
@ -41,7 +41,7 @@ void ReleaseSharedHandle(GLContext* gl,
|
||||
typedef struct {
|
||||
GLenum mTarget;
|
||||
gfx::SurfaceFormat mTextureFormat;
|
||||
gfx3DMatrix mTextureTransform;
|
||||
gfx::Matrix4x4 mTextureTransform;
|
||||
} SharedHandleDetails;
|
||||
|
||||
/**
|
||||
|
@ -47,9 +47,10 @@ void ImageLayer::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurfa
|
||||
// This makes our snapping equivalent to what would happen if our content
|
||||
// was drawn into a ThebesLayer (gfxContext would snap using the local
|
||||
// transform, then we'd snap again when compositing the ThebesLayer).
|
||||
mEffectiveTransform =
|
||||
gfx3DMatrix snappedTransform =
|
||||
SnapTransform(local, sourceRect, nullptr) *
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
gfx::ToMatrix4x4(snappedTransform, mEffectiveTransform);
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "mozilla/TelemetryHistogramEnums.h"
|
||||
#include "mozilla/gfx/2D.h" // for DrawTarget
|
||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
|
||||
#include "mozilla/layers/AsyncPanZoomController.h"
|
||||
#include "mozilla/layers/Compositor.h" // for Compositor
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
@ -552,7 +553,9 @@ bool
|
||||
Layer::MayResample()
|
||||
{
|
||||
gfxMatrix transform2d;
|
||||
return !GetEffectiveTransform().Is2D(&transform2d) ||
|
||||
gfx3DMatrix effectiveTransform;
|
||||
To3DMatrix(GetEffectiveTransform(), effectiveTransform);
|
||||
return !effectiveTransform.Is2D(&transform2d) ||
|
||||
transform2d.HasNonIntegerTranslation() ||
|
||||
AncestorLayerMayChangeTransform(this);
|
||||
}
|
||||
@ -586,7 +589,9 @@ Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
|
||||
nsIntRect scissor = *clipRect;
|
||||
if (!container->UseIntermediateSurface()) {
|
||||
gfxMatrix matrix;
|
||||
DebugOnly<bool> is2D = container->GetEffectiveTransform().Is2D(&matrix);
|
||||
gfx3DMatrix effectiveTransform;
|
||||
To3DMatrix(container->GetEffectiveTransform(), effectiveTransform);
|
||||
DebugOnly<bool> is2D = effectiveTransform.Is2D(&matrix);
|
||||
// See DefaultComputeEffectiveTransforms below
|
||||
NS_ASSERTION(is2D && matrix.PreservesAxisAlignedRectangles(),
|
||||
"Non preserves axis aligned transform with clipped child should have forced intermediate surface");
|
||||
@ -688,14 +693,16 @@ void
|
||||
Layer::ComputeEffectiveTransformForMaskLayer(const gfx3DMatrix& aTransformToSurface)
|
||||
{
|
||||
if (mMaskLayer) {
|
||||
mMaskLayer->mEffectiveTransform = aTransformToSurface;
|
||||
ToMatrix4x4(aTransformToSurface, mMaskLayer->mEffectiveTransform);
|
||||
|
||||
#ifdef DEBUG
|
||||
gfxMatrix maskTranslation;
|
||||
bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D(&maskTranslation);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
#endif
|
||||
mMaskLayer->mEffectiveTransform.PreMultiply(mMaskLayer->GetTransform());
|
||||
Matrix4x4 maskTransform;
|
||||
ToMatrix4x4(mMaskLayer->GetTransform(), maskTransform);
|
||||
mMaskLayer->mEffectiveTransform = maskTransform * mMaskLayer->mEffectiveTransform;
|
||||
}
|
||||
}
|
||||
|
||||
@ -885,7 +892,8 @@ ContainerLayer::DefaultComputeEffectiveTransforms(const gfx3DMatrix& aTransformT
|
||||
gfxMatrix residual;
|
||||
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
|
||||
idealTransform.ProjectTo2D();
|
||||
mEffectiveTransform = SnapTransformTranslation(idealTransform, &residual);
|
||||
gfx3DMatrix snappedTransform = SnapTransformTranslation(idealTransform, &residual);
|
||||
ToMatrix4x4(snappedTransform, mEffectiveTransform);
|
||||
|
||||
bool useIntermediateSurface;
|
||||
if (GetMaskLayer()) {
|
||||
@ -901,7 +909,9 @@ ContainerLayer::DefaultComputeEffectiveTransforms(const gfx3DMatrix& aTransformT
|
||||
} else {
|
||||
useIntermediateSurface = false;
|
||||
gfxMatrix contTransform;
|
||||
if (!mEffectiveTransform.Is2D(&contTransform) ||
|
||||
gfx3DMatrix effectiveTransform;
|
||||
To3DMatrix(mEffectiveTransform, effectiveTransform);
|
||||
if (!effectiveTransform.Is2D(&contTransform) ||
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
!contTransform.PreservesAxisAlignedRectangles()) {
|
||||
#else
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "nsTArrayForwardDeclare.h" // for InfallibleTArray
|
||||
#include "nscore.h" // for nsACString, nsAString
|
||||
#include "prlog.h" // for PRLogModuleInfo
|
||||
#include "gfx2DGlue.h"
|
||||
|
||||
class gfxASurface;
|
||||
class gfxContext;
|
||||
@ -1218,7 +1219,7 @@ public:
|
||||
* ancestor with UseIntermediateSurface() (or to the root, if there is no
|
||||
* such ancestor), but for BasicLayers it's different.
|
||||
*/
|
||||
const gfx3DMatrix& GetEffectiveTransform() const { return mEffectiveTransform; }
|
||||
const gfx::Matrix4x4& GetEffectiveTransform() const { return mEffectiveTransform; }
|
||||
|
||||
/**
|
||||
* @param aTransformToSurface the composition of the transforms
|
||||
@ -1405,7 +1406,7 @@ protected:
|
||||
nsAutoPtr<gfx3DMatrix> mPendingTransform;
|
||||
float mPostXScale;
|
||||
float mPostYScale;
|
||||
gfx3DMatrix mEffectiveTransform;
|
||||
gfx::Matrix4x4 mEffectiveTransform;
|
||||
AnimationArray mAnimations;
|
||||
InfallibleTArray<AnimData> mAnimationData;
|
||||
float mOpacity;
|
||||
@ -1481,8 +1482,9 @@ public:
|
||||
{
|
||||
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
|
||||
gfxMatrix residual;
|
||||
mEffectiveTransform = SnapTransformTranslation(idealTransform,
|
||||
gfx3DMatrix snappedTransform = SnapTransformTranslation(idealTransform,
|
||||
mAllowResidualTranslation ? &residual : nullptr);
|
||||
gfx::ToMatrix4x4(snappedTransform, mEffectiveTransform);
|
||||
// The residual can only be a translation because SnapTransformTranslation
|
||||
// only changes the transform if it's a translation
|
||||
NS_ASSERTION(!residual.HasNonTranslation(),
|
||||
@ -1752,7 +1754,8 @@ public:
|
||||
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
|
||||
{
|
||||
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
|
||||
mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr);
|
||||
gfx3DMatrix snappedTransform = SnapTransformTranslation(idealTransform, nullptr);
|
||||
gfx::ToMatrix4x4(snappedTransform, mEffectiveTransform);
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
}
|
||||
|
||||
@ -1895,10 +1898,11 @@ public:
|
||||
// This makes our snapping equivalent to what would happen if our content
|
||||
// was drawn into a ThebesLayer (gfxContext would snap using the local
|
||||
// transform, then we'd snap again when compositing the ThebesLayer).
|
||||
mEffectiveTransform =
|
||||
gfx3DMatrix snappedTransform =
|
||||
SnapTransform(GetLocalTransform(), gfxRect(0, 0, mBounds.width, mBounds.height),
|
||||
nullptr)*
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
gfx::ToMatrix4x4(snappedTransform, mEffectiveTransform);
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
}
|
||||
|
||||
|
@ -90,10 +90,11 @@ public:
|
||||
// This makes our snapping equivalent to what would happen if our content
|
||||
// was drawn into a ThebesLayer (gfxContext would snap using the local
|
||||
// transform, then we'd snap again when compositing the ThebesLayer).
|
||||
mEffectiveTransform =
|
||||
gfx3DMatrix snappedTransform =
|
||||
SnapTransform(GetLocalTransform(), gfxRect(0, 0, mSize.width, mSize.height),
|
||||
nullptr)*
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
gfx::ToMatrix4x4(snappedTransform, mEffectiveTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,14 +44,15 @@ BasicContainerLayer::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToS
|
||||
idealTransform.ProjectTo2D();
|
||||
|
||||
if (!idealTransform.CanDraw2D()) {
|
||||
mEffectiveTransform = idealTransform;
|
||||
ToMatrix4x4(idealTransform, mEffectiveTransform);
|
||||
ComputeEffectiveTransformsForChildren(gfx3DMatrix());
|
||||
ComputeEffectiveTransformForMaskLayer(gfx3DMatrix());
|
||||
mUseIntermediateSurface = true;
|
||||
return;
|
||||
}
|
||||
|
||||
mEffectiveTransform = SnapTransformTranslation(idealTransform, &residual);
|
||||
gfx3DMatrix snappedTransform = SnapTransformTranslation(idealTransform, &residual);
|
||||
ToMatrix4x4(snappedTransform, mEffectiveTransform);
|
||||
// We always pass the ideal matrix down to our children, so there is no
|
||||
// need to apply any compensation using the residual from SnapTransformTranslation.
|
||||
ComputeEffectiveTransformsForChildren(idealTransform);
|
||||
@ -82,7 +83,9 @@ bool
|
||||
BasicContainerLayer::ChildrenPartitionVisibleRegion(const nsIntRect& aInRect)
|
||||
{
|
||||
gfxMatrix transform;
|
||||
if (!GetEffectiveTransform().CanDraw2D(&transform) ||
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(GetEffectiveTransform(), effectiveTransform);
|
||||
if (!effectiveTransform.CanDraw2D(&transform) ||
|
||||
transform.HasNonIntegerTranslation())
|
||||
return false;
|
||||
|
||||
@ -95,7 +98,9 @@ BasicContainerLayer::ChildrenPartitionVisibleRegion(const nsIntRect& aInRect)
|
||||
continue;
|
||||
|
||||
gfxMatrix childTransform;
|
||||
if (!l->GetEffectiveTransform().CanDraw2D(&childTransform) ||
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(l->GetEffectiveTransform(), effectiveTransform);
|
||||
if (!effectiveTransform.CanDraw2D(&childTransform) ||
|
||||
childTransform.HasNonIntegerTranslation() ||
|
||||
l->GetEffectiveOpacity() != 1.0)
|
||||
return false;
|
||||
|
@ -160,7 +160,8 @@ public:
|
||||
// transform.
|
||||
bool Setup2DTransform()
|
||||
{
|
||||
const gfx3DMatrix& effectiveTransform = mLayer->GetEffectiveTransform();
|
||||
gfx3DMatrix effectiveTransform;
|
||||
To3DMatrix(mLayer->GetEffectiveTransform(), effectiveTransform);
|
||||
// Will return an identity matrix for 3d transforms.
|
||||
return effectiveTransform.CanDraw2D(&mTransform);
|
||||
}
|
||||
@ -403,7 +404,9 @@ MarkLayersHidden(Layer* aLayer, const nsIntRect& aClipRect,
|
||||
// global coordinate system.
|
||||
if (aLayer->GetParent()) {
|
||||
gfxMatrix tr;
|
||||
if (aLayer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(aLayer->GetParent()->GetEffectiveTransform(), effectiveTransform);
|
||||
if (effectiveTransform.CanDraw2D(&tr)) {
|
||||
// Clip rect is applied after aLayer's transform, i.e., in the coordinate
|
||||
// system of aLayer's parent.
|
||||
TransformIntRect(cr, tr, ToInsideIntRect);
|
||||
@ -422,7 +425,9 @@ MarkLayersHidden(Layer* aLayer, const nsIntRect& aClipRect,
|
||||
|
||||
if (!aLayer->AsContainerLayer()) {
|
||||
gfxMatrix transform;
|
||||
if (!aLayer->GetEffectiveTransform().CanDraw2D(&transform)) {
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(aLayer->GetEffectiveTransform(), effectiveTransform);
|
||||
if (!effectiveTransform.CanDraw2D(&transform)) {
|
||||
data->SetHidden(false);
|
||||
return;
|
||||
}
|
||||
@ -483,7 +488,9 @@ ApplyDoubleBuffering(Layer* aLayer, const nsIntRect& aVisibleRect)
|
||||
// global coordinate system.
|
||||
if (aLayer->GetParent()) {
|
||||
gfxMatrix tr;
|
||||
if (aLayer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(aLayer->GetParent()->GetEffectiveTransform(), effectiveTransform);
|
||||
if (effectiveTransform.CanDraw2D(&tr)) {
|
||||
NS_ASSERTION(!tr.HasNonIntegerTranslation(),
|
||||
"Parent can only have an integer translation");
|
||||
cr += nsIntPoint(int32_t(tr.x0), int32_t(tr.y0));
|
||||
@ -983,7 +990,8 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
temp->Paint();
|
||||
}
|
||||
#endif
|
||||
const gfx3DMatrix& effectiveTransform = aLayer->GetEffectiveTransform();
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(aLayer->GetEffectiveTransform(), effectiveTransform);
|
||||
nsRefPtr<gfxASurface> result =
|
||||
Transform3D(untransformedDT->Snapshot(), aTarget, bounds,
|
||||
effectiveTransform, destRect);
|
||||
|
@ -71,8 +71,9 @@ GetMaskData(Layer* aMaskLayer, AutoMaskData* aMaskData)
|
||||
->GetAsSurface(getter_AddRefs(surface), &descriptor) &&
|
||||
(surface || IsSurfaceDescriptorValid(descriptor))) {
|
||||
gfxMatrix transform;
|
||||
DebugOnly<bool> maskIs2D =
|
||||
aMaskLayer->GetEffectiveTransform().CanDraw2D(&transform);
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(aMaskLayer->GetEffectiveTransform(), effectiveTransform);
|
||||
DebugOnly<bool> maskIs2D = effectiveTransform.CanDraw2D(&transform);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
if (surface) {
|
||||
aMaskData->Construct(transform, surface);
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
if (!BasicManager()->IsRetained()) {
|
||||
// Don't do any snapping of our transform, since we're just going to
|
||||
// draw straight through without intermediate buffers.
|
||||
mEffectiveTransform = GetLocalTransform()*aTransformToSurface;
|
||||
gfx::ToMatrix4x4(GetLocalTransform() * aTransformToSurface, mEffectiveTransform);
|
||||
if (gfxPoint(0,0) != mResidualTranslation) {
|
||||
mResidualTranslation = gfxPoint(0,0);
|
||||
mValidRegion.SetEmpty();
|
||||
|
@ -55,7 +55,8 @@ public:
|
||||
if (GetEffectiveVisibleRegion().GetNumRects() != 1 ||
|
||||
!(GetContentFlags() & Layer::CONTENT_OPAQUE))
|
||||
{
|
||||
const gfx3DMatrix& transform3D = GetEffectiveTransform();
|
||||
gfx3DMatrix transform3D;
|
||||
gfx::To3DMatrix(GetEffectiveTransform(), transform3D);
|
||||
gfxMatrix transform;
|
||||
if (HasOpaqueAncestorLayer(this) &&
|
||||
transform3D.Is2D(&transform) &&
|
||||
|
@ -82,12 +82,14 @@ ClientTiledThebesLayer::BeginPaint()
|
||||
|
||||
// Calculate the transform required to convert screen space into transformed
|
||||
// layout device space.
|
||||
gfx3DMatrix layoutToScreen = GetEffectiveTransform();
|
||||
gfx::Matrix4x4 effectiveTransform = GetEffectiveTransform();
|
||||
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
|
||||
if (parent->UseIntermediateSurface()) {
|
||||
layoutToScreen *= parent->GetEffectiveTransform();
|
||||
effectiveTransform = effectiveTransform * parent->GetEffectiveTransform();
|
||||
}
|
||||
}
|
||||
gfx3DMatrix layoutToScreen;
|
||||
gfx::To3DMatrix(effectiveTransform, layoutToScreen);
|
||||
layoutToScreen.ScalePost(metrics.mCumulativeResolution.scale,
|
||||
metrics.mCumulativeResolution.scale,
|
||||
1.f);
|
||||
|
@ -81,7 +81,9 @@ CanvasLayerComposite::RenderLayer(const nsIntRect& aClipRect)
|
||||
// Using the LINEAR filter we get unexplained artifacts.
|
||||
// Use NEAREST when no scaling is required.
|
||||
gfxMatrix matrix;
|
||||
bool is2D = GetEffectiveTransform().Is2D(&matrix);
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(GetEffectiveTransform(), effectiveTransform);
|
||||
bool is2D = effectiveTransform.Is2D(&matrix);
|
||||
if (is2D && !matrix.HasNonTranslationOrFlip()) {
|
||||
filter = GraphicsFilter::FILTER_NEAREST;
|
||||
}
|
||||
@ -90,13 +92,11 @@ CanvasLayerComposite::RenderLayer(const nsIntRect& aClipRect)
|
||||
EffectChain effectChain(this);
|
||||
|
||||
LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(mMaskLayer, effectChain);
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(GetEffectiveTransform(), transform);
|
||||
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
|
||||
mImageHost->Composite(effectChain,
|
||||
GetEffectiveOpacity(),
|
||||
transform,
|
||||
GetEffectiveTransform(),
|
||||
gfx::ToFilter(filter),
|
||||
clipRect);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ColorLayerComposite.h"
|
||||
#include "gfx2DGlue.h" // for ToMatrix4x4
|
||||
#include "gfxColor.h" // for gfxRGBA
|
||||
#include "mozilla/RefPtr.h" // for RefPtr
|
||||
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
|
||||
@ -42,9 +41,7 @@ ColorLayerComposite::RenderLayer(const nsIntRect& aClipRect)
|
||||
|
||||
float opacity = GetEffectiveOpacity();
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(GetEffectiveTransform(), transform);
|
||||
|
||||
const gfx::Matrix4x4& transform = GetEffectiveTransform();
|
||||
mCompositor->DrawQuad(rect, clipRect, effects, opacity, transform);
|
||||
mCompositor->DrawDiagnostics(DIAGNOSTIC_COLOR,
|
||||
rect, clipRect,
|
||||
|
@ -167,8 +167,7 @@ static void DrawVelGraph(const nsIntRect& aClipRect,
|
||||
|
||||
aManager->SetDebugOverlayWantsNextFrame(true);
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(aLayer->GetEffectiveTransform(), transform);
|
||||
const gfx::Matrix4x4& transform = aLayer->GetEffectiveTransform();
|
||||
nsIntRect bounds = aLayer->GetEffectiveVisibleRegion().GetBounds();
|
||||
gfx::Rect graphBounds = gfx::Rect(bounds.x, bounds.y,
|
||||
bounds.width, bounds.height);
|
||||
@ -243,7 +242,8 @@ ContainerRender(ContainerT* aContainer,
|
||||
aContainer->mSupportsComponentAlphaChildren = true;
|
||||
mode = INIT_MODE_NONE;
|
||||
} else {
|
||||
const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform();
|
||||
gfx3DMatrix transform3D;
|
||||
gfx::To3DMatrix(aContainer->GetEffectiveTransform(), transform3D);
|
||||
gfxMatrix transform;
|
||||
// If we have an opaque ancestor layer, then we can be sure that
|
||||
// all the pixels we draw into are either opaque already or will be
|
||||
@ -352,26 +352,20 @@ ContainerRender(ContainerT* aContainer,
|
||||
|
||||
effectChain.mPrimaryEffect = new EffectRenderTarget(surface);
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(aContainer->GetEffectiveTransform(), transform);
|
||||
|
||||
gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height);
|
||||
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
aManager->GetCompositor()->DrawQuad(rect, clipRect, effectChain, opacity,
|
||||
transform);
|
||||
aContainer->GetEffectiveTransform());
|
||||
}
|
||||
|
||||
if (aContainer->GetFrameMetrics().IsScrollable()) {
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(aContainer->GetEffectiveTransform(), transform);
|
||||
|
||||
const FrameMetrics& frame = aContainer->GetFrameMetrics();
|
||||
LayerRect layerBounds = ScreenRect(frame.mCompositionBounds) * ScreenToLayerScale(1.0);
|
||||
gfx::Rect rect(layerBounds.x, layerBounds.y, layerBounds.width, layerBounds.height);
|
||||
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
aManager->GetCompositor()->DrawDiagnostics(DIAGNOSTIC_CONTAINER,
|
||||
rect, clipRect,
|
||||
transform);
|
||||
aContainer->GetEffectiveTransform());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,13 +94,11 @@ ImageLayerComposite::RenderLayer(const nsIntRect& aClipRect)
|
||||
EffectChain effectChain;
|
||||
LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(mMaskLayer, effectChain);
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(GetEffectiveTransform(), transform);
|
||||
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
mImageHost->SetCompositor(mCompositor);
|
||||
mImageHost->Composite(effectChain,
|
||||
GetEffectiveOpacity(),
|
||||
transform,
|
||||
GetEffectiveTransform(),
|
||||
gfx::ToFilter(mFilter),
|
||||
clipRect);
|
||||
}
|
||||
@ -131,9 +129,10 @@ ImageLayerComposite::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToS
|
||||
// This makes our snapping equivalent to what would happen if our content
|
||||
// was drawn into a ThebesLayer (gfxContext would snap using the local
|
||||
// transform, then we'd snap again when compositing the ThebesLayer).
|
||||
mEffectiveTransform =
|
||||
gfx3DMatrix snappedTransform =
|
||||
SnapTransform(local, sourceRect, nullptr) *
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
gfx::ToMatrix4x4(snappedTransform, mEffectiveTransform);
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
}
|
||||
|
||||
|
@ -477,7 +477,7 @@ LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer,
|
||||
// Accumulate the transform of intermediate surfaces
|
||||
gfx3DMatrix transform = aTransform;
|
||||
if (container->UseIntermediateSurface()) {
|
||||
transform = aLayer->GetEffectiveTransform();
|
||||
gfx::To3DMatrix(aLayer->GetEffectiveTransform(), transform);
|
||||
transform.PreMultiply(aTransform);
|
||||
}
|
||||
for (Layer* child = aLayer->GetFirstChild(); child;
|
||||
@ -499,7 +499,8 @@ LayerManagerComposite::ComputeRenderIntegrityInternal(Layer* aLayer,
|
||||
|
||||
if (!incompleteRegion.IsEmpty()) {
|
||||
// Calculate the transform to get between screen and layer space
|
||||
gfx3DMatrix transformToScreen = aLayer->GetEffectiveTransform();
|
||||
gfx3DMatrix transformToScreen;
|
||||
To3DMatrix(aLayer->GetEffectiveTransform(), transformToScreen);
|
||||
transformToScreen.PreMultiply(aTransform);
|
||||
|
||||
SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen);
|
||||
@ -577,7 +578,8 @@ LayerManagerComposite::ComputeRenderIntegrity()
|
||||
// This is derived from the code in
|
||||
// AsyncCompositionManager::TransformScrollableLayer
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
gfx3DMatrix transform = primaryScrollable->GetEffectiveTransform();
|
||||
gfx3DMatrix transform;
|
||||
gfx::To3DMatrix(primaryScrollable->GetEffectiveTransform(), transform);
|
||||
transform.ScalePost(metrics.mResolution.scale, metrics.mResolution.scale, 1);
|
||||
|
||||
// Clip the screen rect to the document bounds
|
||||
@ -720,9 +722,7 @@ LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(aMaskLayer->GetEffectiveTransform(), transform);
|
||||
if (!mCompositable->AddMaskEffect(aEffects, transform, aIs3D)) {
|
||||
if (!mCompositable->AddMaskEffect(aEffects, aMaskLayer->GetEffectiveTransform(), aIs3D)) {
|
||||
mCompositable = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -105,8 +105,6 @@ ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect)
|
||||
mBuffer->GetLayer() == this,
|
||||
"buffer is corrupted");
|
||||
|
||||
gfx::Matrix4x4 transform;
|
||||
ToMatrix4x4(GetEffectiveTransform(), transform);
|
||||
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
@ -134,7 +132,7 @@ ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect)
|
||||
|
||||
mBuffer->Composite(effectChain,
|
||||
GetEffectiveOpacity(),
|
||||
transform,
|
||||
GetEffectiveTransform(),
|
||||
gfx::Filter::LINEAR,
|
||||
clipRect,
|
||||
&visibleRegion,
|
||||
|
@ -35,8 +35,8 @@ ColorLayerD3D10::RenderLayer()
|
||||
color[2] = (float)(mColor.b * opacity);
|
||||
color[3] = opacity;
|
||||
|
||||
const gfx3DMatrix& transform = GetEffectiveTransform();
|
||||
void* raw = &const_cast<gfx3DMatrix&>(transform)._11;
|
||||
const gfx::Matrix4x4& transform = GetEffectiveTransform();
|
||||
void* raw = &const_cast<gfx::Matrix4x4&>(transform)._11;
|
||||
effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);
|
||||
effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color);
|
||||
|
||||
|
@ -106,7 +106,8 @@ ContainerLayerD3D10::RenderLayer()
|
||||
previousViewportSize = mD3DManager->GetViewport();
|
||||
|
||||
if (mVisibleRegion.GetNumRects() != 1 || !(GetContentFlags() & CONTENT_OPAQUE)) {
|
||||
const gfx3DMatrix& transform3D = GetEffectiveTransform();
|
||||
gfx3DMatrix transform3D;
|
||||
gfx::To3DMatrix(GetEffectiveTransform(), transform3D);
|
||||
gfxMatrix transform;
|
||||
// If we have an opaque ancestor layer, then we can be sure that
|
||||
// all the pixels we draw into are either opaque already or will be
|
||||
@ -247,7 +248,8 @@ ContainerLayerD3D10::Validate()
|
||||
mSupportsComponentAlphaChildren = false;
|
||||
|
||||
if (UseIntermediateSurface()) {
|
||||
const gfx3DMatrix& transform3D = GetEffectiveTransform();
|
||||
gfx3DMatrix transform3D;
|
||||
gfx::To3DMatrix(GetEffectiveTransform(), transform3D);
|
||||
gfxMatrix transform;
|
||||
|
||||
if (mVisibleRegion.GetNumRects() == 1 && (GetContentFlags() & CONTENT_OPAQUE)) {
|
||||
|
@ -860,7 +860,9 @@ LayerD3D10::LoadMaskTexture()
|
||||
}
|
||||
|
||||
gfxMatrix maskTransform;
|
||||
bool maskIs2D = maskLayer->GetEffectiveTransform().CanDraw2D(&maskTransform);
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(maskLayer->GetEffectiveTransform(), effectiveTransform);
|
||||
bool maskIs2D = effectiveTransform.CanDraw2D(&maskTransform);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
gfxRect bounds = gfxRect(gfxPoint(), ThebesIntSize(size));
|
||||
bounds = maskTransform.TransformBounds(bounds);
|
||||
|
@ -238,8 +238,8 @@ public:
|
||||
void SetEffectTransformAndOpacity()
|
||||
{
|
||||
Layer* layer = GetLayer();
|
||||
const gfx3DMatrix& transform = layer->GetEffectiveTransform();
|
||||
void* raw = &const_cast<gfx3DMatrix&>(transform)._11;
|
||||
const gfx::Matrix4x4& transform = layer->GetEffectiveTransform();
|
||||
void* raw = &const_cast<gfx::Matrix4x4&>(transform)._11;
|
||||
effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);
|
||||
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(layer->GetEffectiveOpacity());
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ RenderColorLayerD3D9(ColorLayer* aLayer, LayerManagerD3D9 *aManager)
|
||||
bounds.height),
|
||||
1);
|
||||
|
||||
const gfx3DMatrix& transform = aLayer->GetEffectiveTransform();
|
||||
const gfx::Matrix4x4& transform = aLayer->GetEffectiveTransform();
|
||||
aManager->device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
|
||||
|
||||
gfxRGBA layerColor(aLayer->GetColor());
|
||||
|
@ -89,7 +89,8 @@ ContainerLayerD3D9::RenderLayer()
|
||||
// don't need a background, we're going to paint all opaque stuff
|
||||
mSupportsComponentAlphaChildren = true;
|
||||
} else {
|
||||
const gfx3DMatrix& transform3D = GetEffectiveTransform();
|
||||
gfx3DMatrix transform3D;
|
||||
gfx::To3DMatrix(GetEffectiveTransform(), transform3D);
|
||||
gfxMatrix transform;
|
||||
// If we have an opaque ancestor layer, then we can be sure that
|
||||
// all the pixels we draw into are either opaque already or will be
|
||||
|
@ -552,18 +552,20 @@ LoadMaskTexture(Layer* aMask, IDirect3DDevice9* aDevice,
|
||||
gfx::IntSize size;
|
||||
nsRefPtr<IDirect3DTexture9> texture =
|
||||
static_cast<LayerD3D9*>(aMask->ImplData())->GetAsTexture(&size);
|
||||
|
||||
|
||||
if (!texture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
gfxMatrix maskTransform;
|
||||
bool maskIs2D = aMask->GetEffectiveTransform().CanDraw2D(&maskTransform);
|
||||
gfx3DMatrix effectiveTransform;
|
||||
gfx::To3DMatrix(aMask->GetEffectiveTransform(), effectiveTransform);
|
||||
bool maskIs2D = effectiveTransform.CanDraw2D(&maskTransform);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
gfxRect bounds = gfxRect(gfxPoint(), gfx::ThebesIntSize(size));
|
||||
bounds = maskTransform.TransformBounds(bounds);
|
||||
|
||||
aDevice->SetVertexShaderConstantF(DeviceManagerD3D9::sMaskQuadRegister,
|
||||
aDevice->SetVertexShaderConstantF(DeviceManagerD3D9::sMaskQuadRegister,
|
||||
ShaderConstantRect((float)bounds.x,
|
||||
(float)bounds.y,
|
||||
(float)bounds.width,
|
||||
|
@ -225,7 +225,7 @@ public:
|
||||
void SetShaderTransformAndOpacity()
|
||||
{
|
||||
Layer* layer = GetLayer();
|
||||
const gfx3DMatrix& transform = layer->GetEffectiveTransform();
|
||||
const gfx::Matrix4x4& transform = layer->GetEffectiveTransform();
|
||||
device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
|
||||
|
||||
float opacity[4];
|
||||
|
@ -215,7 +215,7 @@ nsEventStatus GestureEventListener::HandlePinchGestureEvent(const MultiTouchInpu
|
||||
|
||||
if (mTouches.Length() > 1 && !aClearTouches) {
|
||||
const ScreenIntPoint& firstTouch = mTouches[0].mScreenPoint,
|
||||
secondTouch = mTouches[mTouches.Length() - 1].mScreenPoint;
|
||||
secondTouch = mTouches[1].mScreenPoint;
|
||||
ScreenPoint focusPoint = ScreenPoint(firstTouch + secondTouch) / 2;
|
||||
ScreenIntPoint delta = secondTouch - firstTouch;
|
||||
float currentSpan = float(NS_hypot(delta.x, delta.y));
|
||||
|
@ -1215,7 +1215,8 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
|
||||
AutoBindTexture bindSource(mGLContext, source->AsSourceOGL(), LOCAL_GL_TEXTURE0);
|
||||
|
||||
GraphicsFilter filter = ThebesFilter(texturedEffect->mFilter);
|
||||
gfx3DMatrix textureTransform = source->AsSourceOGL()->GetTextureTransform();
|
||||
gfx3DMatrix textureTransform;
|
||||
gfx::To3DMatrix(source->AsSourceOGL()->GetTextureTransform(), textureTransform);
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
gfxMatrix textureTransform2D;
|
||||
|
@ -378,13 +378,13 @@ SharedTextureSourceOGL::gl() const
|
||||
return mCompositor ? mCompositor->gl() : nullptr;
|
||||
}
|
||||
|
||||
gfx3DMatrix
|
||||
gfx::Matrix4x4
|
||||
SharedTextureSourceOGL::GetTextureTransform()
|
||||
{
|
||||
SharedHandleDetails handleDetails;
|
||||
if (!GetSharedHandleDetails(gl(), mShareType, mSharedHandle, handleDetails)) {
|
||||
NS_WARNING("Could not get shared handle details");
|
||||
return gfx3DMatrix();
|
||||
return gfx::Matrix4x4();
|
||||
}
|
||||
|
||||
return handleDetails.mTextureTransform;
|
||||
@ -883,7 +883,7 @@ SharedDeprecatedTextureHostOGL::Unlock()
|
||||
}
|
||||
|
||||
|
||||
gfx3DMatrix
|
||||
gfx::Matrix4x4
|
||||
SharedDeprecatedTextureHostOGL::GetTextureTransform()
|
||||
{
|
||||
SharedHandleDetails handleDetails;
|
||||
|
@ -12,12 +12,12 @@
|
||||
#include "GLContextTypes.h" // for GLContext
|
||||
#include "GLDefs.h" // for GLenum, LOCAL_GL_CLAMP_TO_EDGE, etc
|
||||
#include "GLTextureImage.h" // for TextureImage
|
||||
#include "gfx3DMatrix.h" // for gfx3DMatrix
|
||||
#include "gfxTypes.h"
|
||||
#include "mozilla/GfxMessageUtils.h" // for gfxContentType
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
|
||||
#include "mozilla/RefPtr.h" // for RefPtr
|
||||
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
|
||||
#include "mozilla/gfx/Point.h" // for IntSize, IntPoint
|
||||
#include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
|
||||
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags
|
||||
@ -135,7 +135,7 @@ public:
|
||||
|
||||
virtual GLenum GetWrapMode() const = 0;
|
||||
|
||||
virtual gfx3DMatrix GetTextureTransform() { return gfx3DMatrix(); }
|
||||
virtual gfx::Matrix4x4 GetTextureTransform() { return gfx::Matrix4x4(); }
|
||||
|
||||
virtual TextureImageDeprecatedTextureHostOGL* AsTextureImageDeprecatedTextureHost() { return nullptr; }
|
||||
};
|
||||
@ -258,7 +258,7 @@ public:
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
|
||||
|
||||
virtual gfx3DMatrix GetTextureTransform() MOZ_OVERRIDE;
|
||||
virtual gfx::Matrix4x4 GetTextureTransform() MOZ_OVERRIDE;
|
||||
|
||||
virtual GLenum GetTextureTarget() const { return mTextureTarget; }
|
||||
|
||||
@ -744,7 +744,7 @@ public:
|
||||
gfxContentType::COLOR;
|
||||
}
|
||||
|
||||
virtual gfx3DMatrix GetTextureTransform() MOZ_OVERRIDE;
|
||||
virtual gfx::Matrix4x4 GetTextureTransform() MOZ_OVERRIDE;
|
||||
|
||||
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "gfxImageSurface.h"
|
||||
#include "AndroidBridge.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -72,7 +73,7 @@ public:
|
||||
env->CallObjectMethod(aSurfaceTexture, jSurfaceTexture_updateTexImage);
|
||||
}
|
||||
|
||||
bool GetTransformMatrix(jobject aSurfaceTexture, gfx3DMatrix& aMatrix)
|
||||
bool GetTransformMatrix(jobject aSurfaceTexture, gfx::Matrix4x4& aMatrix)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
|
||||
@ -102,7 +103,7 @@ public:
|
||||
aMatrix._42 = array[13];
|
||||
aMatrix._43 = array[14];
|
||||
aMatrix._44 = array[15];
|
||||
|
||||
|
||||
env->ReleaseFloatArrayElements(jarray, array, 0);
|
||||
|
||||
return false;
|
||||
@ -213,7 +214,7 @@ nsSurfaceTexture::UpdateTexImage()
|
||||
}
|
||||
|
||||
bool
|
||||
nsSurfaceTexture::GetTransformMatrix(gfx3DMatrix& aMatrix)
|
||||
nsSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix)
|
||||
{
|
||||
return sJNIFunctions.GetTransformMatrix(mSurfaceTexture, aMatrix);
|
||||
}
|
||||
|
@ -11,11 +11,16 @@
|
||||
#include <jni.h>
|
||||
#include "nsIRunnable.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfx3DMatrix.h"
|
||||
#include "GLDefs.h"
|
||||
|
||||
class gfxASurface;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class Matrix4x4;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a wrapper around Android's SurfaceTexture class.
|
||||
* Usage is pretty much exactly like the Java class, so see
|
||||
@ -41,7 +46,7 @@ public:
|
||||
// This attaches the updated data to the TEXTURE_EXTERNAL target
|
||||
void UpdateTexImage();
|
||||
|
||||
bool GetTransformMatrix(gfx3DMatrix& aMatrix);
|
||||
bool GetTransformMatrix(mozilla::gfx::Matrix4x4& aMatrix);
|
||||
int ID() { return mID; }
|
||||
|
||||
// The callback is guaranteed to be called on the main thread even
|
||||
|
@ -134,7 +134,7 @@ ConnectWorkerToNFC::RunTask(JSContext* aCx)
|
||||
// communication.
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
|
||||
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
|
||||
JSObject* workerGlobal = JS::CurrentGlobalOrNull(aCx);
|
||||
JS::Rooted<JSObject*> workerGlobal(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
|
||||
return !!JS_DefineFunction(aCx, workerGlobal,
|
||||
"postNfcMessage", PostToNFC, 1, 0);
|
||||
|
@ -141,7 +141,7 @@ ConnectWorkerToRIL::RunTask(JSContext *aCx)
|
||||
// communication.
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
|
||||
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
|
||||
JSObject *workerGlobal = JS::CurrentGlobalOrNull(aCx);
|
||||
JS::Rooted<JSObject*> workerGlobal(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
|
||||
return !!JS_DefineFunction(aCx, workerGlobal,
|
||||
"postRILMessage", PostToRIL, 2, 0);
|
||||
|
@ -430,6 +430,7 @@ JavaScriptParent::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
if (outparams.Length() != outobjects.length())
|
||||
return ipcfail(cx);
|
||||
|
||||
RootedObject obj(cx);
|
||||
for (size_t i = 0; i < outparams.Length(); i++) {
|
||||
// Don't bother doing anything for outparams that weren't set.
|
||||
if (outparams[i].type() == JSParam::Tvoid_t)
|
||||
@ -440,7 +441,7 @@ JavaScriptParent::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
|
||||
if (!toValue(cx, outparams[i], &v))
|
||||
return false;
|
||||
|
||||
JSObject *obj = &outobjects[i].toObject();
|
||||
obj = &outobjects[i].toObject();
|
||||
if (!JS_SetProperty(cx, obj, "value", v))
|
||||
return false;
|
||||
}
|
||||
|
@ -264,14 +264,6 @@ struct JSStringFinalizer {
|
||||
void (*finalize)(const JSStringFinalizer *fin, jschar *chars);
|
||||
};
|
||||
|
||||
// JSClass.checkAccess type: check whether obj[id] may be accessed per mode,
|
||||
// returning false on error/exception, true on success with obj[id]'s last-got
|
||||
// value in *vp, and its attributes in *attrsp. As for JSPropertyOp above, id
|
||||
// is either a string or an int jsval.
|
||||
typedef bool
|
||||
(* JSCheckAccessOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JSAccessMode mode, JS::MutableHandleValue vp);
|
||||
|
||||
// Return whether the first principal subsumes the second. The exact meaning of
|
||||
// 'subsumes' is left up to the browser. Subsumption is checked inside the JS
|
||||
// engine when determining, e.g., which stack frames to display in a backtrace.
|
||||
@ -410,7 +402,6 @@ typedef void
|
||||
\
|
||||
/* Optional members (may be null). */ \
|
||||
FinalizeOp finalize; \
|
||||
JSCheckAccessOp checkAccess; \
|
||||
JSNative call; \
|
||||
JSHasInstanceOp hasInstance; \
|
||||
JSNative construct; \
|
||||
@ -510,7 +501,6 @@ struct JSClass {
|
||||
|
||||
// Optional members (may be null).
|
||||
JSFinalizeOp finalize;
|
||||
JSCheckAccessOp checkAccess;
|
||||
JSNative call;
|
||||
JSHasInstanceOp hasInstance;
|
||||
JSNative construct;
|
||||
@ -639,7 +629,6 @@ JS_STATIC_ASSERT(offsetof(JSClass, enumerate) == offsetof(Class, enumerate));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, resolve) == offsetof(Class, resolve));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, convert) == offsetof(Class, convert));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, finalize) == offsetof(Class, finalize));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, checkAccess) == offsetof(Class, checkAccess));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, call) == offsetof(Class, call));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, construct) == offsetof(Class, construct));
|
||||
JS_STATIC_ASSERT(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance));
|
||||
|
@ -95,40 +95,117 @@ enum Reason {
|
||||
|
||||
} /* namespace gcreason */
|
||||
|
||||
/*
|
||||
* Zone GC:
|
||||
*
|
||||
* SpiderMonkey's GC is capable of performing a collection on an arbitrary
|
||||
* subset of the zones in the system. This allows an embedding to minimize
|
||||
* collection time by only collecting zones that have run code recently,
|
||||
* ignoring the parts of the heap that are unlikely to have changed.
|
||||
*
|
||||
* When triggering a GC using one of the functions below, it is first necessary
|
||||
* to select the zones to be collected. To do this, you can call
|
||||
* PrepareZoneForGC on each zone, or you can call PrepareForFullGC to select
|
||||
* all zones. Failing to select any zone is an error.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Schedule the given zone to be collected as part of the next GC.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
PrepareZoneForGC(Zone *zone);
|
||||
|
||||
/*
|
||||
* Schedule all zones to be collected in the next GC.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
PrepareForFullGC(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* When performing an incremental GC, the zones that were selected for the
|
||||
* previous incremental slice must be selected in subsequent slices as well.
|
||||
* This function selects those slices automatically.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
PrepareForIncrementalGC(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Returns true if any zone in the system has been scheduled for GC with one of
|
||||
* the functions above or by the JS engine.
|
||||
*/
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsGCScheduled(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Undoes the effect of the Prepare methods above. The given zone will not be
|
||||
* collected in the next GC.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
SkipZoneForGC(Zone *zone);
|
||||
|
||||
/*
|
||||
* When triggering a GC using one of the functions below, it is first necessary
|
||||
* to select the compartments to be collected. To do this, you can call
|
||||
* PrepareZoneForGC on each compartment, or you can call PrepareForFullGC
|
||||
* to select all compartments. Failing to select any compartment is an error.
|
||||
* Non-Incremental GC:
|
||||
*
|
||||
* The following functions perform a non-incremental GC.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Performs a non-incremental collection of all selected zones. Some objects
|
||||
* that are unreachable from the program may still be alive afterwards because
|
||||
* of internal references.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
GCForReason(JSRuntime *rt, gcreason::Reason reason);
|
||||
|
||||
/*
|
||||
* Perform a non-incremental collection after clearing caches and other
|
||||
* temporary references to objects. This will remove all unreferenced objects
|
||||
* in the system.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
ShrinkingGC(JSRuntime *rt, gcreason::Reason reason);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
ShrinkGCBuffers(JSRuntime *rt);
|
||||
/*
|
||||
* Incremental GC:
|
||||
*
|
||||
* Incremental GC divides the full mark-and-sweep collection into multiple
|
||||
* slices, allowing client JavaScript code to run between each slice. This
|
||||
* allows interactive apps to avoid long collection pauses. Incremental GC does
|
||||
* not make collection take less time, it merely spreads that time out so that
|
||||
* the pauses are less noticable.
|
||||
*
|
||||
* For a collection to be carried out incrementally the following conditions
|
||||
* must be met:
|
||||
* - The collection must be run by calling JS::IncrementalGC() rather than
|
||||
* JS_GC().
|
||||
* - The GC mode must have been set to JSGC_MODE_INCREMENTAL with
|
||||
* JS_SetGCParameter().
|
||||
* - All native objects that have their own trace hook must indicate that they
|
||||
* implement read and write barriers with the JSCLASS_IMPLEMENTS_BARRIERS
|
||||
* flag.
|
||||
*
|
||||
* Note: Even if incremental GC is enabled and working correctly,
|
||||
* non-incremental collections can still happen when low on memory.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Begin an incremental collection and perform one slice worth of work or
|
||||
* perform a slice of an ongoing incremental collection. When this function
|
||||
* returns, the collection is not complete. This function must be called
|
||||
* repeatedly until !IsIncrementalGCInProgress(rt).
|
||||
*
|
||||
* Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or
|
||||
* shorter than the requested interval.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis = 0);
|
||||
|
||||
/*
|
||||
* If IsIncrementalGCInProgress(rt), this call finishes the ongoing collection
|
||||
* by performing an arbitrarily long slice. If !IsIncrementalGCInProgress(rt),
|
||||
* this is equivalent to GCForReason. When this function returns,
|
||||
* IsIncrementalGCInProgress(rt) will always be false.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason);
|
||||
|
||||
@ -162,40 +239,56 @@ struct JS_FRIEND_API(GCDescription) {
|
||||
typedef void
|
||||
(* GCSliceCallback)(JSRuntime *rt, GCProgress progress, const GCDescription &desc);
|
||||
|
||||
/*
|
||||
* The GC slice callback is called at the beginning and end of each slice. This
|
||||
* callback may be used for GC notifications as well as to perform additional
|
||||
* marking.
|
||||
*/
|
||||
extern JS_FRIEND_API(GCSliceCallback)
|
||||
SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback);
|
||||
|
||||
/*
|
||||
* Signals a good place to do an incremental slice, because the browser is
|
||||
* drawing a frame.
|
||||
* Incremental GC defaults to enabled, but may be disabled for testing or in
|
||||
* embeddings that have not yet implemented barriers on their native classes.
|
||||
* There is not currently a way to re-enable incremental GC once it has been
|
||||
* disabled on the runtime.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
NotifyDidPaint(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalGCEnabled(JSRuntime *rt);
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalGCInProgress(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
DisableIncrementalGC(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
DisableGenerationalGC(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
EnableGenerationalGC(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Returns true if incremental GC is enabled. Simply having incremental GC
|
||||
* enabled is not sufficient to ensure incremental collections are happening.
|
||||
* See the comment "Incremental GC" above for reasons why incremental GC may be
|
||||
* suppressed. Inspection of the "nonincremental reason" field of the
|
||||
* GCDescription returned by GCSliceCallback may help narrow down the cause if
|
||||
* collections are not happening incrementally when expected.
|
||||
*/
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsGenerationalGCEnabled(JSRuntime *rt);
|
||||
IsIncrementalGCEnabled(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Returns true while an incremental GC is ongoing, both when actively
|
||||
* collecting and between slices.
|
||||
*/
|
||||
JS_FRIEND_API(bool)
|
||||
IsIncrementalGCInProgress(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Returns true when writes to GC things must call an incremental (pre) barrier.
|
||||
* This is generally only true when running mutator code in-between GC slices.
|
||||
* At other times, the barrier may be elided for performance.
|
||||
*/
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSRuntime *rt);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsIncrementalBarrierNeeded(JSContext *cx);
|
||||
|
||||
/*
|
||||
* Notify the GC that a reference to a GC thing is about to be overwritten.
|
||||
* These methods must be called if IsIncrementalBarrierNeeded.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalReferenceBarrier(void *ptr, JSGCTraceKind kind);
|
||||
|
||||
@ -205,16 +298,68 @@ IncrementalValueBarrier(const Value &v);
|
||||
extern JS_FRIEND_API(void)
|
||||
IncrementalObjectBarrier(JSObject *obj);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
PokeGC(JSRuntime *rt);
|
||||
|
||||
/* Was the most recent GC run incrementally? */
|
||||
/*
|
||||
* Returns true if the most recent GC ran incrementally.
|
||||
*/
|
||||
extern JS_FRIEND_API(bool)
|
||||
WasIncrementalGC(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Generational GC:
|
||||
*
|
||||
* Note: Generational GC is not yet enabled by default. The following functions
|
||||
* are non-functional unless SpiderMonkey was configured with
|
||||
* --enable-gcgenerational.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generational GC is enabled by default. Use this method to disable it.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
DisableGenerationalGC(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Generational GC may be re-enabled at runtime.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
EnableGenerationalGC(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Returns true if generational allocation and collection is currently enabled
|
||||
* on the given runtime.
|
||||
*/
|
||||
extern JS_FRIEND_API(bool)
|
||||
IsGenerationalGCEnabled(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Returns the GC's "number". This does not correspond directly to the number
|
||||
* of GCs that have been run, but is guaranteed to be monotonically increasing
|
||||
* with GC activity.
|
||||
*/
|
||||
extern JS_FRIEND_API(size_t)
|
||||
GetGCNumber();
|
||||
|
||||
/*
|
||||
* The GC does not immediately return the unused memory freed by a collection
|
||||
* back to the system incase it is needed soon afterwards. This call forces the
|
||||
* GC to return this memory immediately.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
ShrinkGCBuffers(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Assert if any GC occured while this guard object was live. This is most
|
||||
* useful to help the exact rooting hazard analysis in complex regions, since
|
||||
* it cannot understand dataflow.
|
||||
*
|
||||
* Note: GC behavior is unpredictable even when deterministice and is generally
|
||||
* non-deterministic in practice. The fact that this guard has not
|
||||
* asserted is not a guarantee that a GC cannot happen in the guarded
|
||||
* region. As a rule, anyone performing a GC unsafe action should
|
||||
* understand the GC properties of all code in that region and ensure
|
||||
* that the hazard analysis is correct for that code, rather than relying
|
||||
* on this class.
|
||||
*/
|
||||
class JS_PUBLIC_API(AutoAssertNoGC)
|
||||
{
|
||||
#ifdef JS_DEBUG
|
||||
@ -346,6 +491,20 @@ MarkStringAsLive(Zone *zone, JSString *string)
|
||||
MarkGCThingAsLive(rt, string, JSTRACE_STRING);
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal to Firefox.
|
||||
*
|
||||
* Note: this is not related to the PokeGC in nsJSEnvironment.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
PokeGC(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Internal to Firefox.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
NotifyDidPaint(JSRuntime *rt);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* js_GCAPI_h */
|
||||
|
@ -63,8 +63,6 @@ EXTRA_DSO_LDOPTS += $(NSPR_LIBS)
|
||||
|
||||
GARBAGE += jsautokw.h host_jskwgen$(HOST_BIN_SUFFIX)
|
||||
|
||||
GARBAGE += jsautooplen.h host_jsoplengen$(HOST_BIN_SUFFIX)
|
||||
|
||||
GARBAGE += selfhosted.out.h
|
||||
|
||||
USE_HOST_CXX = 1
|
||||
@ -408,13 +406,8 @@ endif
|
||||
$(CURDIR)/jsautokw.h: host_jskwgen$(HOST_BIN_SUFFIX)
|
||||
./host_jskwgen$(HOST_BIN_SUFFIX) $@
|
||||
|
||||
# Use CURDIR to avoid finding a jsautooplen.h in the source tree (from
|
||||
# a previous build?) via VPATH when we're building in a separate tree.
|
||||
$(CURDIR)/jsautooplen.h: host_jsoplengen$(HOST_BIN_SUFFIX)
|
||||
./host_jsoplengen$(HOST_BIN_SUFFIX) $@
|
||||
|
||||
# Force auto-header generation before compiling any source that may use them
|
||||
$(OBJS): $(CURDIR)/jsautokw.h $(CURDIR)/jsautooplen.h
|
||||
$(OBJS): $(CURDIR)/jsautokw.h
|
||||
|
||||
ifdef MOZ_ETW
|
||||
ETWProvider.h ETWProvider.rc ETWProvider.mof: ETWProvider.man
|
||||
|
@ -1014,7 +1014,6 @@ const Class MapObject::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
finalize,
|
||||
nullptr, // checkAccess
|
||||
nullptr, // call
|
||||
nullptr, // hasInstance
|
||||
nullptr, // construct
|
||||
@ -1605,7 +1604,6 @@ const Class SetObject::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
finalize,
|
||||
nullptr, // checkAccess
|
||||
nullptr, // call
|
||||
nullptr, // hasInstance
|
||||
nullptr, // construct
|
||||
|
@ -572,11 +572,6 @@ obj_watch(JSContext *cx, unsigned argc, Value *vp)
|
||||
if (!ValueToId<CanGC>(cx, args[0], &propid))
|
||||
return false;
|
||||
|
||||
RootedValue tmp(cx);
|
||||
unsigned attrs;
|
||||
if (!CheckAccess(cx, obj, propid, JSACC_WATCH, &tmp, &attrs))
|
||||
return false;
|
||||
|
||||
if (!JSObject::watch(cx, obj, propid, callable))
|
||||
return false;
|
||||
|
||||
|
@ -108,7 +108,6 @@ const Class X4Type::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
nullptr, /* finalize */
|
||||
nullptr, /* checkAccess */
|
||||
call, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
nullptr, /* construct */
|
||||
@ -287,7 +286,6 @@ const Class SIMDObject::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
nullptr, /* finalize */
|
||||
nullptr, /* checkAccess */
|
||||
nullptr, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
nullptr, /* construct */
|
||||
|
@ -1309,7 +1309,6 @@ const Class CloneBufferObject::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
Finalize,
|
||||
nullptr, /* checkAccess */
|
||||
nullptr, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
nullptr, /* construct */
|
||||
|
@ -39,7 +39,6 @@ const Class TypeRepresentation::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
obj_finalize,
|
||||
nullptr, /* checkAccess */
|
||||
nullptr, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
nullptr, /* construct */
|
||||
|
@ -373,7 +373,6 @@ const Class js::ScalarType::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
nullptr,
|
||||
nullptr,
|
||||
ScalarType::call,
|
||||
nullptr,
|
||||
nullptr,
|
||||
@ -444,7 +443,6 @@ const Class js::ReferenceType::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
nullptr,
|
||||
nullptr,
|
||||
ReferenceType::call,
|
||||
nullptr,
|
||||
nullptr,
|
||||
@ -566,7 +564,6 @@ const Class ArrayType::class_ = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
TypedObject::construct,
|
||||
nullptr
|
||||
};
|
||||
@ -847,7 +844,6 @@ const Class StructType::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
nullptr, /* finalize */
|
||||
nullptr, /* checkAccess */
|
||||
nullptr, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
TypedObject::construct,
|
||||
@ -2271,7 +2267,6 @@ const Class TypedObject::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
TypedDatum::obj_finalize,
|
||||
nullptr, /* checkAccess */
|
||||
nullptr, /* call */
|
||||
nullptr, /* construct */
|
||||
nullptr, /* hasInstance */
|
||||
@ -2439,7 +2434,6 @@ const Class TypedHandle::class_ = {
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
TypedDatum::obj_finalize,
|
||||
nullptr, /* checkAccess */
|
||||
nullptr, /* call */
|
||||
nullptr, /* construct */
|
||||
nullptr, /* hasInstance */
|
||||
|
@ -485,7 +485,7 @@ static const JSClass sCTypeProtoClass = {
|
||||
JSCLASS_HAS_RESERVED_SLOTS(CTYPEPROTO_SLOTS),
|
||||
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nullptr,
|
||||
nullptr, ConstructAbstract, nullptr, ConstructAbstract
|
||||
ConstructAbstract, nullptr, ConstructAbstract
|
||||
};
|
||||
|
||||
// Class representing ctypes.CData.prototype and the 'prototype' properties
|
||||
@ -502,7 +502,7 @@ static const JSClass sCTypeClass = {
|
||||
JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(CTYPE_SLOTS),
|
||||
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CType::Finalize,
|
||||
nullptr, CType::ConstructData, CType::HasInstance, CType::ConstructData,
|
||||
CType::ConstructData, CType::HasInstance, CType::ConstructData,
|
||||
CType::Trace
|
||||
};
|
||||
|
||||
@ -511,7 +511,7 @@ static const JSClass sCDataClass = {
|
||||
JSCLASS_HAS_RESERVED_SLOTS(CDATA_SLOTS),
|
||||
JS_PropertyStub, JS_DeletePropertyStub, ArrayType::Getter, ArrayType::Setter,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CData::Finalize,
|
||||
nullptr, FunctionType::Call, nullptr, FunctionType::Call
|
||||
FunctionType::Call, nullptr, FunctionType::Call
|
||||
};
|
||||
|
||||
static const JSClass sCClosureClass = {
|
||||
@ -519,7 +519,7 @@ static const JSClass sCClosureClass = {
|
||||
JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(CCLOSURE_SLOTS),
|
||||
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CClosure::Finalize,
|
||||
nullptr, nullptr, nullptr, nullptr, CClosure::Trace
|
||||
nullptr, nullptr, nullptr, CClosure::Trace
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1318,10 +1318,8 @@ using namespace js;
|
||||
using namespace js::ctypes;
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_InitCTypesClass(JSContext* cx, JSObject *globalArg)
|
||||
JS_InitCTypesClass(JSContext* cx, HandleObject global)
|
||||
{
|
||||
RootedObject global(cx, globalArg);
|
||||
|
||||
// attach ctypes property to global object
|
||||
RootedObject ctypes(cx, JS_NewObject(cx, &sCTypesGlobalClass, NullPtr(), NullPtr()));
|
||||
if (!ctypes)
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jsautooplen.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsfun.h"
|
||||
#include "jsnum.h"
|
||||
|
@ -9,8 +9,6 @@
|
||||
|
||||
#include "gc/Nursery-inl.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "jscompartment.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsinfer.h"
|
||||
@ -22,6 +20,7 @@
|
||||
#ifdef JS_ION
|
||||
#include "jit/IonFrames.h"
|
||||
#endif
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "vm/ArrayObject.h"
|
||||
#include "vm/Debugger.h"
|
||||
#if defined(DEBUG)
|
||||
@ -247,6 +246,24 @@ js::Nursery::notifyInitialSlots(Cell *cell, HeapSlot *slots)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
js::Nursery::notifyNewElements(gc::Cell *cell, ObjectElements *elements)
|
||||
{
|
||||
JS_ASSERT(!isInside(elements));
|
||||
notifyInitialSlots(cell, reinterpret_cast<HeapSlot *>(elements));
|
||||
}
|
||||
|
||||
void
|
||||
js::Nursery::notifyRemovedElements(gc::Cell *cell, ObjectElements *oldElements)
|
||||
{
|
||||
JS_ASSERT(cell);
|
||||
JS_ASSERT(oldElements);
|
||||
JS_ASSERT(!isInside(oldElements));
|
||||
|
||||
if (isInside(cell))
|
||||
hugeSlots.remove(reinterpret_cast<HeapSlot *>(oldElements));
|
||||
}
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
@ -679,9 +696,35 @@ js::Nursery::collect(JSRuntime *rt, JS::gcreason::Reason reason, TypeObjectList
|
||||
/* Move objects pointed to by roots from the nursery to the major heap. */
|
||||
MinorCollectionTracer trc(rt, this);
|
||||
|
||||
TIME_START(markStoreBuffer);
|
||||
rt->gcStoreBuffer.mark(&trc); // This must happen first.
|
||||
TIME_END(markStoreBuffer);
|
||||
/* Mark the store buffer. This must happen first. */
|
||||
StoreBuffer &sb = rt->gcStoreBuffer;
|
||||
TIME_START(markValues);
|
||||
sb.markValues(&trc);
|
||||
TIME_END(markValues);
|
||||
|
||||
TIME_START(markCells);
|
||||
sb.markCells(&trc);
|
||||
TIME_END(markCells);
|
||||
|
||||
TIME_START(markSlots);
|
||||
sb.markSlots(&trc);
|
||||
TIME_END(markSlots);
|
||||
|
||||
TIME_START(markWholeCells);
|
||||
sb.markWholeCells(&trc);
|
||||
TIME_END(markWholeCells);
|
||||
|
||||
TIME_START(markRelocatableValues);
|
||||
sb.markRelocatableValues(&trc);
|
||||
TIME_END(markRelocatableValues);
|
||||
|
||||
TIME_START(markRelocatableCells);
|
||||
sb.markRelocatableCells(&trc);
|
||||
TIME_END(markRelocatableCells);
|
||||
|
||||
TIME_START(markGenericEntries);
|
||||
sb.markGenericEntries(&trc);
|
||||
TIME_END(markGenericEntries);
|
||||
|
||||
TIME_START(checkHashTables);
|
||||
CheckHashTablesAfterMovingGC(rt);
|
||||
@ -741,11 +784,18 @@ js::Nursery::collect(JSRuntime *rt, JS::gcreason::Reason reason, TypeObjectList
|
||||
TIME_END(pretenure);
|
||||
|
||||
/* Sweep. */
|
||||
TIME_START(freeHugeSlots);
|
||||
freeHugeSlots(rt);
|
||||
TIME_END(freeHugeSlots);
|
||||
|
||||
TIME_START(sweep);
|
||||
sweep(rt);
|
||||
rt->gcStoreBuffer.clear();
|
||||
TIME_END(sweep);
|
||||
|
||||
TIME_START(clearStoreBuffer);
|
||||
rt->gcStoreBuffer.clear();
|
||||
TIME_END(clearStoreBuffer);
|
||||
|
||||
/*
|
||||
* We ignore gcMaxBytes when allocating for minor collection. However, if we
|
||||
* overflowed, we disable the nursery. The next time we allocate, we'll fail
|
||||
@ -763,15 +813,25 @@ js::Nursery::collect(JSRuntime *rt, JS::gcreason::Reason reason, TypeObjectList
|
||||
static bool printedHeader = false;
|
||||
if (!printedHeader) {
|
||||
fprintf(stderr,
|
||||
"MinorGC time: Total WaitBg mkStrBf ckHshTb mkRuntm mkDbggr clrNOC collect updtIon resize pretnur sweep\n");
|
||||
"MinorGC: Reason PRate Size Time WaitBg mkVals mkClls mkSlts mkWCll mkRVal mkRCll mkGnrc ckTbls mkRntm mkDbgr clrNOC collct updtIn resize pretnr frSlts clrSB sweep\n");
|
||||
printedHeader = true;
|
||||
}
|
||||
|
||||
#define FMT " %7" PRIu64
|
||||
fprintf(stderr, "MinorGC time:" FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT "\n",
|
||||
#define FMT " %6" PRIu64
|
||||
fprintf(stderr,
|
||||
"MinorGC: %20s %5.1f%% %4d" FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT "\n",
|
||||
js::gcstats::ExplainReason(reason),
|
||||
promotionRate * 100,
|
||||
numActiveChunks_,
|
||||
totalTime,
|
||||
TIME_TOTAL(waitBgSweep),
|
||||
TIME_TOTAL(markStoreBuffer),
|
||||
TIME_TOTAL(markValues),
|
||||
TIME_TOTAL(markCells),
|
||||
TIME_TOTAL(markSlots),
|
||||
TIME_TOTAL(markWholeCells),
|
||||
TIME_TOTAL(markRelocatableValues),
|
||||
TIME_TOTAL(markRelocatableCells),
|
||||
TIME_TOTAL(markGenericEntries),
|
||||
TIME_TOTAL(checkHashTables),
|
||||
TIME_TOTAL(markRuntime),
|
||||
TIME_TOTAL(markDebugger),
|
||||
@ -780,6 +840,8 @@ js::Nursery::collect(JSRuntime *rt, JS::gcreason::Reason reason, TypeObjectList
|
||||
TIME_TOTAL(updateJitActivations),
|
||||
TIME_TOTAL(resize),
|
||||
TIME_TOTAL(pretenure),
|
||||
TIME_TOTAL(freeHugeSlots),
|
||||
TIME_TOTAL(clearStoreBuffer),
|
||||
TIME_TOTAL(sweep));
|
||||
#undef FMT
|
||||
}
|
||||
@ -787,13 +849,16 @@ js::Nursery::collect(JSRuntime *rt, JS::gcreason::Reason reason, TypeObjectList
|
||||
}
|
||||
|
||||
void
|
||||
js::Nursery::sweep(JSRuntime *rt)
|
||||
js::Nursery::freeHugeSlots(JSRuntime *rt)
|
||||
{
|
||||
/* Free malloced pointers owned by freed things in the nursery. */
|
||||
for (HugeSlotsSet::Range r = hugeSlots.all(); !r.empty(); r.popFront())
|
||||
rt->defaultFreeOp()->free_(r.front());
|
||||
hugeSlots.clear();
|
||||
}
|
||||
|
||||
void
|
||||
js::Nursery::sweep(JSRuntime *rt)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
/* Poison the nursery contents so touching a freed object will crash. */
|
||||
JS_POISON((void *)start(), SweptNursery, NurserySize - sizeof(JSRuntime *));
|
||||
|
@ -104,6 +104,12 @@ class Nursery
|
||||
/* Add a slots to our tracking list if it is out-of-line. */
|
||||
void notifyInitialSlots(gc::Cell *cell, HeapSlot *slots);
|
||||
|
||||
/* Add elements to our tracking list if it is out-of-line. */
|
||||
void notifyNewElements(gc::Cell *cell, ObjectElements *elements);
|
||||
|
||||
/* Remove elements to our tracking list if it is out-of-line. */
|
||||
void notifyRemovedElements(gc::Cell *cell, ObjectElements *oldElements);
|
||||
|
||||
typedef Vector<types::TypeObject *, 0, SystemAllocPolicy> TypeObjectList;
|
||||
|
||||
/*
|
||||
@ -266,10 +272,12 @@ class Nursery
|
||||
void setElementsForwardingPointer(ObjectElements *oldHeader, ObjectElements *newHeader,
|
||||
uint32_t nelems);
|
||||
|
||||
/* Free malloced pointers owned by freed things in the nursery. */
|
||||
void freeHugeSlots(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Frees all non-live nursery-allocated things at the end of a minor
|
||||
* collection. This operation takes time proportional to the number of
|
||||
* dead things.
|
||||
* collection.
|
||||
*/
|
||||
void sweep(JSRuntime *rt);
|
||||
|
||||
|
@ -239,8 +239,8 @@ class gcstats::StatisticsSerializer
|
||||
*/
|
||||
JS_STATIC_ASSERT(JS::gcreason::NUM_TELEMETRY_REASONS >= JS::gcreason::NUM_REASONS);
|
||||
|
||||
static const char *
|
||||
ExplainReason(JS::gcreason::Reason reason)
|
||||
const char *
|
||||
js::gcstats::ExplainReason(JS::gcreason::Reason reason)
|
||||
{
|
||||
switch (reason) {
|
||||
#define SWITCH_REASON(name) \
|
||||
|
@ -248,6 +248,8 @@ struct AutoSCC
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
const char *ExplainReason(JS::gcreason::Reason reason);
|
||||
|
||||
} /* namespace gcstats */
|
||||
} /* namespace js */
|
||||
|
||||
|
@ -120,6 +120,7 @@ template <typename T>
|
||||
void
|
||||
StoreBuffer::MonoTypeBuffer<T>::mark(StoreBuffer *owner, JSTracer *trc)
|
||||
{
|
||||
JS_ASSERT(owner->isEnabled());
|
||||
ReentrancyGuard g(*owner);
|
||||
if (!storage_)
|
||||
return;
|
||||
@ -188,6 +189,7 @@ StoreBuffer::RelocatableMonoTypeBuffer<T>::compact(StoreBuffer *owner)
|
||||
void
|
||||
StoreBuffer::GenericBuffer::mark(StoreBuffer *owner, JSTracer *trc)
|
||||
{
|
||||
JS_ASSERT(owner->isEnabled());
|
||||
ReentrancyGuard g(*owner);
|
||||
if (!storage_)
|
||||
return;
|
||||
@ -279,10 +281,8 @@ StoreBuffer::clear()
|
||||
}
|
||||
|
||||
void
|
||||
StoreBuffer::mark(JSTracer *trc)
|
||||
StoreBuffer::markAll(JSTracer *trc)
|
||||
{
|
||||
JS_ASSERT(isEnabled());
|
||||
|
||||
bufferVal.mark(this, trc);
|
||||
bufferCell.mark(this, trc);
|
||||
bufferSlot.mark(this, trc);
|
||||
|
@ -437,8 +437,15 @@ class StoreBuffer
|
||||
put(bufferGeneric, CallbackRef<Key>(callback, key, data));
|
||||
}
|
||||
|
||||
/* Mark the source of all edges in the store buffer. */
|
||||
void mark(JSTracer *trc);
|
||||
/* Methods to mark the source of all edges in the store buffer. */
|
||||
void markAll(JSTracer *trc);
|
||||
void markValues(JSTracer *trc) { bufferVal.mark(this, trc); }
|
||||
void markCells(JSTracer *trc) { bufferCell.mark(this, trc); }
|
||||
void markSlots(JSTracer *trc) { bufferSlot.mark(this, trc); }
|
||||
void markWholeCells(JSTracer *trc) { bufferWholeCell.mark(this, trc); }
|
||||
void markRelocatableValues(JSTracer *trc) { bufferRelocVal.mark(this, trc); }
|
||||
void markRelocatableCells(JSTracer *trc) { bufferRelocCell.mark(this, trc); }
|
||||
void markGenericEntries(JSTracer *trc) { bufferGeneric.mark(this, trc); }
|
||||
|
||||
/* We cannot call InParallelSection directly because of a circular dependency. */
|
||||
bool inParallelSection() const;
|
||||
|
@ -769,7 +769,7 @@ js::gc::EndVerifyPostBarriers(JSRuntime *rt)
|
||||
if (!edges.init())
|
||||
goto oom;
|
||||
trc->edges = &edges;
|
||||
rt->gcStoreBuffer.mark(trc);
|
||||
rt->gcStoreBuffer.markAll(trc);
|
||||
|
||||
/* Walk the heap to find any edges not the the |edges| set. */
|
||||
JS_TracerInit(trc, rt, PostVerifierVisitEdge);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user