Merge m-i to m-c

This commit is contained in:
Phil Ringnalda 2014-01-25 19:55:19 -08:00
commit 7cb58aa799
204 changed files with 2586 additions and 2172 deletions

View File

@ -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.

View File

@ -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
{

View File

@ -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.

View File

@ -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();

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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; }
/**

View File

@ -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;

View File

@ -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;
};

View File

@ -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]

View 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);
}

View File

@ -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>

View File

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

View File

@ -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".
*

View File

@ -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);

View File

@ -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().

View File

@ -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,
};

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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) {

View File

@ -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);
}

View File

@ -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()

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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
};

View File

@ -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,

View File

@ -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 \

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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));

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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");

View File

@ -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);
}

View File

@ -767,7 +767,6 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
// Security policy:
static JSSecurityCallbacks securityCallbacks = {
nullptr,
ContentSecurityPolicyAllows
};
JS_SetSecurityCallbacks(aRuntime, &securityCallbacks);

View File

@ -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
};
//----------------------------------------------------------------------

View File

@ -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);

View File

@ -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

View File

@ -41,7 +41,7 @@ void ReleaseSharedHandle(GLContext* gl,
typedef struct {
GLenum mTarget;
gfx::SurfaceFormat mTextureFormat;
gfx3DMatrix mTextureTransform;
gfx::Matrix4x4 mTextureTransform;
} SharedHandleDetails;
/**

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}
/**

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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) &&

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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());
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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);

View File

@ -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)) {

View File

@ -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);

View File

@ -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());
}

View File

@ -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());

View File

@ -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

View File

@ -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,

View File

@ -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];

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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));

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -1309,7 +1309,6 @@ const Class CloneBufferObject::class_ = {
JS_ResolveStub,
JS_ConvertStub,
Finalize,
nullptr, /* checkAccess */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */

View File

@ -39,7 +39,6 @@ const Class TypeRepresentation::class_ = {
JS_ResolveStub,
JS_ConvertStub,
obj_finalize,
nullptr, /* checkAccess */
nullptr, /* call */
nullptr, /* hasInstance */
nullptr, /* construct */

View File

@ -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 */

View File

@ -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)

View File

@ -18,7 +18,6 @@
#include "jsapi.h"
#include "jsatom.h"
#include "jsautooplen.h"
#include "jscntxt.h"
#include "jsfun.h"
#include "jsnum.h"

View File

@ -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 *));

View File

@ -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);

View File

@ -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) \

View File

@ -248,6 +248,8 @@ struct AutoSCC
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
const char *ExplainReason(JS::gcreason::Reason reason);
} /* namespace gcstats */
} /* namespace js */

View File

@ -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);

View File

@ -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;

View File

@ -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