Merge m-c to fx-team a=merge

This commit is contained in:
Wes Kocher 2014-09-15 16:49:06 -07:00
commit c162d16ff6
106 changed files with 4072 additions and 1395 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3b740054007bde98875b2def11eac24cf9c20e5c"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3b740054007bde98875b2def11eac24cf9c20e5c"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "b0a272695ccf247884000f785ed4cbfe49ae4141",
"revision": "123eb4378d299e61d73be5e290f7d9ca00f2fb41",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3b740054007bde98875b2def11eac24cf9c20e5c"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="855be6ade407c26e0596e7306a44deebc3f60933"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e2d70bee03b5380ac327a145e5d694fb2443f018"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f293787d4a86257c9e78a35bd3f73b31b706e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

File diff suppressed because it is too large Load Diff

View File

@ -682,7 +682,7 @@ function gKeywordURIFixup({ target: browser, data: fixupInfo }) {
// whether the original input would be vaguely interpretable as a URL,
// so figure that out first.
let alternativeURI = deserializeURI(fixupInfo.fixedURI);
if (!fixupInfo.fixupUsedKeyword || !alternativeURI) {
if (!fixupInfo.fixupUsedKeyword || !alternativeURI || !alternativeURI.host) {
return;
}

View File

@ -925,7 +925,6 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
nsIPrincipal* aPrincipal,
InfallibleTArray<nsString>* aJSONRetVal)
{
AutoSafeJSContext cx;
nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
mListeners.Get(aMessage);
if (listeners) {
@ -956,11 +955,23 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
if (!wrappedJS) {
continue;
}
JS::Rooted<JSObject*> object(cx, wrappedJS->GetJSObject());
if (!object) {
if (!wrappedJS->GetJSObject()) {
continue;
}
JSAutoCompartment ac(cx, object);
// Note - The ergonomics here will get a lot better with bug 971673:
//
// AutoEntryScript aes;
// if (!aes.Init(wrappedJS->GetJSObject())) {
// continue;
// }
// JSContext* cx = aes.cx();
nsIGlobalObject* nativeGlobal =
xpc::GetNativeForGlobal(js::GetGlobalForObjectCrossCompartment(wrappedJS->GetJSObject()));
AutoEntryScript aes(nativeGlobal);
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> object(cx, wrappedJS->GetJSObject());
// The parameter for the listener function.
JS::Rooted<JSObject*> param(cx,

View File

@ -9,6 +9,7 @@ var is_remote;
(function start() {
[is_remote] = sendSyncMessage("cpows:is_remote");
parent_test();
error_reporting_test();
dom_test();
xray_test();
compartment_test();
@ -89,6 +90,10 @@ function parent_test()
sendSyncMessage("cpows:parent_test", {}, {func: f});
}
function error_reporting_test() {
sendSyncMessage("cpows:error_reporting_test", {}, {});
}
function dom_test()
{
let element = content.document.createElement("div");

View File

@ -33,7 +33,12 @@
}
// Make sure that an error in this file actually causes the test to fail.
var gReceivedErrorProbe = false;
window.onerror = function (msg, url, line) {
if (/Test Error Probe/.test(msg)) {
gReceivedErrorProbe = true;
return;
}
ok(false, "Error while executing: \n" + msg + "\n" + url + ":" + line);
};
@ -175,6 +180,11 @@
savedMM.sendAsyncMessage("cpows:from_parent", {}, {obj: obj});
}
// Make sure errors in this file actually hit window.onerror.
function recvErrorReportingTest(message) {
throw "Test Error Probe";
}
let savedElement = null;
function recvDomTest(message) {
savedElement = message.objects.element;
@ -271,6 +281,7 @@
mm.addMessageListener("cpows:done", recvDoneMessage);
mm.addMessageListener("cpows:fail", recvFailMessage);
mm.addMessageListener("cpows:parent_test", recvParentTest);
mm.addMessageListener("cpows:error_reporting_test", recvErrorReportingTest);
mm.addMessageListener("cpows:dom_test", recvDomTest);
mm.addMessageListener("cpows:dom_test_after_gc", recvDomTestAfterGC);
mm.addMessageListener("cpows:xray_test", recvXrayTest);
@ -285,6 +296,7 @@
}
function finish() {
ok(gReceivedErrorProbe, "Should have reported error probe");
opener.setTimeout("done()", 0);
window.close();
}

View File

@ -7,7 +7,6 @@ support-files =
[test_BufferedSeek.html]
[test_FrameSelection.html]
skip-if = os == "mac"
[test_MediaSource.html]
[test_SplitAppendDelay.html]
[test_SplitAppend.html]

View File

@ -49,10 +49,10 @@ runWithMSE(function () {
first = false;
} else {
ms.endOfStream();
target = targets.shift();
v.currentTime = target.currentTime;
}
});
target = targets.shift();
v.currentTime = target.currentTime;
});
});

View File

@ -114,6 +114,8 @@ GetValueFromString(const nsAString& aString,
return IsValidUnitType(*aUnitType);
}
static float GetMMPerPixel() { return MM_PER_INCH_FLOAT / 96; }
static float
FixAxisLength(float aLength)
{
@ -124,22 +126,73 @@ FixAxisLength(float aLength)
return aLength;
}
float
nsSVGLength2::GetAxisLength(SVGSVGElement *aCtx) const
SVGElementMetrics::SVGElementMetrics(nsSVGElement* aSVGElement,
SVGSVGElement* aCtx)
: mSVGElement(aSVGElement)
, mCtx(aCtx)
{
if (!aCtx)
return 1;
return FixAxisLength(aCtx->GetLength(mCtxType));
}
float
nsSVGLength2::GetAxisLength(nsIFrame *aNonSVGFrame) const
SVGElementMetrics::GetEmLength() const
{
gfx::Size size =
nsSVGIntegrationUtils::GetSVGCoordContextForNonSVGFrame(aNonSVGFrame);
return SVGContentUtils::GetFontSize(mSVGElement);
}
float
SVGElementMetrics::GetExLength() const
{
return SVGContentUtils::GetFontXHeight(mSVGElement);
}
float
SVGElementMetrics::GetAxisLength(uint8_t aCtxType) const
{
if (!EnsureCtx()) {
return 1;
}
return FixAxisLength(mCtx->GetLength(aCtxType));
}
bool
SVGElementMetrics::EnsureCtx() const
{
if (!mCtx && mSVGElement) {
mCtx = mSVGElement->GetCtx();
}
return mCtx != nullptr;
}
NonSVGFrameUserSpaceMetrics::NonSVGFrameUserSpaceMetrics(nsIFrame* aFrame)
: mFrame(aFrame)
{
}
float
NonSVGFrameUserSpaceMetrics::GetEmLength() const
{
return SVGContentUtils::GetFontSize(mFrame);
}
float
NonSVGFrameUserSpaceMetrics::GetExLength() const
{
return SVGContentUtils::GetFontXHeight(mFrame);
}
gfx::Size
NonSVGFrameUserSpaceMetrics::GetSize() const
{
return nsSVGIntegrationUtils::GetSVGCoordContextForNonSVGFrame(mFrame);
}
float
UserSpaceMetricsWithSize::GetAxisLength(uint8_t aCtxType) const
{
gfx::Size size = GetSize();
float length;
switch (mCtxType) {
switch (aCtxType) {
case SVGContentUtils::X:
length = size.width;
break;
@ -161,55 +214,28 @@ float
nsSVGLength2::GetUnitScaleFactor(nsSVGElement *aSVGElement,
uint8_t aUnitType) const
{
switch (aUnitType) {
case nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER:
case nsIDOMSVGLength::SVG_LENGTHTYPE_PX:
return 1;
case nsIDOMSVGLength::SVG_LENGTHTYPE_EMS:
return 1 / GetEmLength(aSVGElement);
case nsIDOMSVGLength::SVG_LENGTHTYPE_EXS:
return 1 / GetExLength(aSVGElement);
}
return GetUnitScaleFactor(aSVGElement->GetCtx(), aUnitType);
return GetUnitScaleFactor(SVGElementMetrics(aSVGElement), aUnitType);
}
float
nsSVGLength2::GetUnitScaleFactor(SVGSVGElement *aCtx, uint8_t aUnitType) const
{
switch (aUnitType) {
case nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER:
case nsIDOMSVGLength::SVG_LENGTHTYPE_PX:
return 1;
case nsIDOMSVGLength::SVG_LENGTHTYPE_MM:
return GetMMPerPixel();
case nsIDOMSVGLength::SVG_LENGTHTYPE_CM:
return GetMMPerPixel() / 10.0f;
case nsIDOMSVGLength::SVG_LENGTHTYPE_IN:
return GetMMPerPixel() / MM_PER_INCH_FLOAT;
case nsIDOMSVGLength::SVG_LENGTHTYPE_PT:
return GetMMPerPixel() * POINTS_PER_INCH_FLOAT / MM_PER_INCH_FLOAT;
case nsIDOMSVGLength::SVG_LENGTHTYPE_PC:
return GetMMPerPixel() * POINTS_PER_INCH_FLOAT / MM_PER_INCH_FLOAT / 12.0f;
case nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE:
return 100.0f / GetAxisLength(aCtx);
case nsIDOMSVGLength::SVG_LENGTHTYPE_EMS:
return 1 / GetEmLength(aCtx);
case nsIDOMSVGLength::SVG_LENGTHTYPE_EXS:
return 1 / GetExLength(aCtx);
default:
NS_NOTREACHED("Unknown unit type");
return 0;
}
return GetUnitScaleFactor(SVGElementMetrics(aCtx, aCtx), aUnitType);
}
float
nsSVGLength2::GetUnitScaleFactor(nsIFrame *aFrame, uint8_t aUnitType) const
{
nsIContent* content = aFrame->GetContent();
if (content->IsSVG())
return GetUnitScaleFactor(static_cast<nsSVGElement*>(content), aUnitType);
if (content->IsSVG()) {
return GetUnitScaleFactor(SVGElementMetrics(static_cast<nsSVGElement*>(content)), aUnitType);
}
return GetUnitScaleFactor(NonSVGFrameUserSpaceMetrics(aFrame), aUnitType);
}
float
nsSVGLength2::GetUnitScaleFactor(const UserSpaceMetrics& aMetrics, uint8_t aUnitType) const
{
switch (aUnitType) {
case nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER:
case nsIDOMSVGLength::SVG_LENGTHTYPE_PX:
@ -225,11 +251,11 @@ nsSVGLength2::GetUnitScaleFactor(nsIFrame *aFrame, uint8_t aUnitType) const
case nsIDOMSVGLength::SVG_LENGTHTYPE_PC:
return GetMMPerPixel() * POINTS_PER_INCH_FLOAT / MM_PER_INCH_FLOAT / 12.0f;
case nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE:
return 100.0f / GetAxisLength(aFrame);
return 100.0f / aMetrics.GetAxisLength(mCtxType);
case nsIDOMSVGLength::SVG_LENGTHTYPE_EMS:
return 1 / GetEmLength(aFrame);
return 1 / aMetrics.GetEmLength();
case nsIDOMSVGLength::SVG_LENGTHTYPE_EXS:
return 1 / GetExLength(aFrame);
return 1 / aMetrics.GetExLength();
default:
NS_NOTREACHED("Unknown unit type");
return 0;

View File

@ -16,6 +16,7 @@
#include "nsMathUtils.h"
#include "nsSVGElement.h"
#include "SVGContentUtils.h"
#include "mozilla/gfx/Rect.h"
class nsIFrame;
class nsSMILValue;
@ -29,10 +30,64 @@ class SVGSVGElement;
}
}
namespace mozilla {
namespace dom {
class UserSpaceMetrics
{
public:
virtual ~UserSpaceMetrics() {}
virtual float GetEmLength() const = 0;
virtual float GetExLength() const = 0;
virtual float GetAxisLength(uint8_t aCtxType) const = 0;
};
class UserSpaceMetricsWithSize : public UserSpaceMetrics
{
public:
virtual gfx::Size GetSize() const = 0;
virtual float GetAxisLength(uint8_t aCtxType) const MOZ_OVERRIDE;
};
class SVGElementMetrics : public UserSpaceMetrics
{
public:
SVGElementMetrics(nsSVGElement* aSVGElement,
mozilla::dom::SVGSVGElement* aCtx = nullptr);
virtual float GetEmLength() const MOZ_OVERRIDE;
virtual float GetExLength() const MOZ_OVERRIDE;
virtual float GetAxisLength(uint8_t aCtxType) const MOZ_OVERRIDE;
private:
bool EnsureCtx() const;
nsSVGElement* mSVGElement;
mutable mozilla::dom::SVGSVGElement* mCtx;
};
class NonSVGFrameUserSpaceMetrics : public UserSpaceMetricsWithSize
{
public:
NonSVGFrameUserSpaceMetrics(nsIFrame* aFrame);
virtual float GetEmLength() const MOZ_OVERRIDE;
virtual float GetExLength() const MOZ_OVERRIDE;
virtual gfx::Size GetSize() const MOZ_OVERRIDE;
private:
nsIFrame* mFrame;
};
}
}
class nsSVGLength2
{
friend class mozilla::dom::SVGAnimatedLength;
friend class mozilla::DOMSVGLength;
typedef mozilla::dom::UserSpaceMetrics UserSpaceMetrics;
public:
void Init(uint8_t aCtxType = SVGContentUtils::XY,
uint8_t aAttrEnum = 0xff,
@ -63,10 +118,15 @@ public:
float GetBaseValue(nsSVGElement* aSVGElement) const
{ return mBaseVal / GetUnitScaleFactor(aSVGElement, mSpecifiedUnitType); }
float GetAnimValue(nsSVGElement* aSVGElement) const
{ return mAnimVal / GetUnitScaleFactor(aSVGElement, mSpecifiedUnitType); }
float GetAnimValue(nsIFrame* aFrame) const
{ return mAnimVal / GetUnitScaleFactor(aFrame, mSpecifiedUnitType); }
float GetAnimValue(mozilla::dom::SVGSVGElement* aCtx) const
{ return mAnimVal / GetUnitScaleFactor(aCtx, mSpecifiedUnitType); }
float GetAnimValue(const UserSpaceMetrics& aMetrics) const
{ return mAnimVal / GetUnitScaleFactor(aMetrics, mSpecifiedUnitType); }
uint8_t GetCtxType() const { return mCtxType; }
uint8_t GetSpecifiedUnitType() const { return mSpecifiedUnitType; }
@ -77,8 +137,6 @@ public:
float GetBaseValue(mozilla::dom::SVGSVGElement* aCtx) const
{ return mBaseVal / GetUnitScaleFactor(aCtx, mSpecifiedUnitType); }
float GetAnimValue(mozilla::dom::SVGSVGElement* aCtx) const
{ return mAnimVal / GetUnitScaleFactor(aCtx, mSpecifiedUnitType); }
bool HasBaseVal() const {
return mIsBaseSet;
@ -106,21 +164,9 @@ private:
uint8_t mCtxType; // X, Y or Unspecified
bool mIsAnimated:1;
bool mIsBaseSet:1;
static float GetMMPerPixel() { return MM_PER_INCH_FLOAT / 96; }
float GetAxisLength(nsIFrame *aNonSVGFrame) const;
static float GetEmLength(nsIFrame *aFrame)
{ return SVGContentUtils::GetFontSize(aFrame); }
static float GetExLength(nsIFrame *aFrame)
{ return SVGContentUtils::GetFontXHeight(aFrame); }
float GetUnitScaleFactor(nsIFrame *aFrame, uint8_t aUnitType) const;
float GetMMPerPixel(mozilla::dom::SVGSVGElement *aCtx) const;
float GetAxisLength(mozilla::dom::SVGSVGElement *aCtx) const;
static float GetEmLength(nsSVGElement *aSVGElement)
{ return SVGContentUtils::GetFontSize(aSVGElement); }
static float GetExLength(nsSVGElement *aSVGElement)
{ return SVGContentUtils::GetFontXHeight(aSVGElement); }
float GetUnitScaleFactor(nsIFrame *aFrame, uint8_t aUnitType) const;
float GetUnitScaleFactor(const UserSpaceMetrics& aMetrics, uint8_t aUnitType) const;
float GetUnitScaleFactor(nsSVGElement *aSVGElement, uint8_t aUnitType) const;
float GetUnitScaleFactor(mozilla::dom::SVGSVGElement *aCtx, uint8_t aUnitType) const;

View File

@ -117,9 +117,7 @@ public:
* transparent one.
*
* Note: So ObjectIsNativeWrapper(cx, obj) check usually means "through xray
* wrapper this part is not visible" while combined with
* || xpc::WrapperFactory::XrayWrapperNotShadowing(obj) it means "through
* xray wrapper it is visible only if it does not hide any native property."
* wrapper this part is not visible".
*/
static bool ObjectIsNativeWrapper(JSContext* cx, JSObject* obj);

View File

@ -468,7 +468,22 @@ SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
if (outer) {
globalObject = static_cast<nsGlobalWindow*>(outer->GetCurrentInnerWindow());
}
} else {
}
// We run addons in a separate privileged compartment, but they still expect
// to trigger the onerror handler of their associated DOMWindow.
//
// Note that the way we do this right now is sloppy. Error reporters can
// theoretically be triggered at arbitrary times (not just immediately before
// an AutoJSAPI comes off the stack), so we don't really have a way of knowing
// that the global of the current compartment is the correct global with which
// to report the error. But in practice this is probably fine for the time
// being, and will get cleaned up soon when we fix bug 981187.
if (!globalObject && JS::CurrentGlobalOrNull(cx)) {
globalObject = xpc::AddonWindowOrNull(JS::CurrentGlobalOrNull(cx));
}
if (!globalObject) {
globalObject = xpc::GetNativeForGlobal(xpc::PrivilegedJunkScope());
}

View File

@ -842,6 +842,10 @@ MaybeWrapValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
// GetWrapperPreserveColor() which can return its existing wrapper, if any, and
// a WrapObject() which will try to create a wrapper. Typically, this is done by
// having "value" inherit from nsWrapperCache.
//
// The value stored in rval will be ready to be exposed to whatever JS
// is running on cx right now. In particular, it will be in the
// compartment of cx, and outerized as needed.
template <class T>
MOZ_ALWAYS_INLINE bool
WrapNewBindingObject(JSContext* cx, T* value, JS::MutableHandle<JS::Value> rval)

View File

@ -57,6 +57,9 @@ function SettingsLock(aSettingsManager) {
"Settings:Finalize:OK", "Settings:Finalize:KO"]);
this.sendMessage("Settings:CreateLock", {lockID: this._id, isServiceLock: false});
Services.tm.currentThread.dispatch(this._closeHelper.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
// We only want to file closeHelper once per set of receiveMessage calls.
this._closeCalled = true;
}
SettingsLock.prototype = {
@ -84,8 +87,9 @@ SettingsLock.prototype = {
_closeHelper: function() {
if (DEBUG) debug("closing lock " + this._id);
this._open = false;
this._closeCalled = false;
if (!this._requests || Object.keys(this._requests).length == 0) {
if (DEBUG) debug("Requests exhausted, finalizing");
if (DEBUG) debug("Requests exhausted, finalizing " + this._id);
this._settingsManager.unregisterLock(this._id);
this.sendMessage("Settings:Finalize", {lockID: this._id});
} else {
@ -150,7 +154,11 @@ SettingsLock.prototype = {
// things like marionetteScriptFinished in them. Make sure we file
// our call to run/finalize BEFORE opening the lock and fulfilling
// DOMRequests.
Services.tm.currentThread.dispatch(this._closeHelper.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
if (!this._closeCalled) {
// We only want to file closeHelper once per set of receiveMessage calls.
Services.tm.currentThread.dispatch(this._closeHelper.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
this._closeCalled = true;
}
if (DEBUG) debug("receiveMessage: " + aMessage.name);
switch (aMessage.name) {
case "Settings:Get:OK":

View File

@ -574,14 +574,14 @@ let SettingsRequestManager = {
if (DEBUG) debug("Lock no longer alive, cannot run tasks");
return;
}
if (lock.finalizing) {
debug("TASK TRYING TO QUEUE AFTER FINALIZE CALLED. THIS IS BAD. Lock: " + aLockID);
return;
}
let currentTask = lock.tasks.shift();
let promises = [];
while (currentTask) {
if (DEBUG) debug("Running Operation " + currentTask.operation);
if (lock.finalizing) {
Cu.reportError("Settings lock trying to run more tasks after finalizing. Ignoring tasks, but this is bad. Lock: " + aLockID);
continue;
}
let p;
switch (currentTask.operation) {
case "get":

View File

@ -138,8 +138,6 @@ var steps = [
ok(true, "All requests on a failed lock should fail");
var lock = mozSettings.createLock();
lock.onsettingstransactionfailure = function (evt) {
// Stop listening at this point
lock.onsettingstransactionfailure = null;
ok(evt.error == "Lock failed a permissions check, all requests now failing.", "transaction failure on permissions error message correct.");
ok(true, "transaction failed (expected) ");
next();

View File

@ -3091,7 +3091,8 @@ RilObject.prototype = {
// ("Yes/No") command with command qualifier set to "Yes/No", it shall
// supply the value '01' when the answer is "positive" and the value
// '00' when the answer is "negative" in the Text string data object.
text = response.isYesNo ? 0x01 : 0x00;
text = response.isYesNo ? String.fromCharCode(0x01)
: String.fromCharCode(0x00);
} else {
text = response.input;
}

View File

@ -156,6 +156,81 @@ add_test(function test_stk_terminal_response() {
context.RIL.sendStkTerminalResponse(response);
});
/**
* Verify STK terminal response : GET_INKEY - YES/NO request
*/
add_test(function test_stk_terminal_response_get_inkey() {
function do_test(isYesNo) {
let worker = newUint8SupportOutgoingIndexWorker();
let context = worker.ContextPool._contexts[0];
let buf = context.Buf;
let pduHelper = context.GsmPDUHelper;
buf.sendParcel = function() {
// Type
do_check_eq(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
// Token : we don't care
this.readInt32();
// Data Size, 32 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
// TLV_DEVICE_ID_SIZE(4) +
// TLV_RESULT_SIZE(3) +
// TEXT LENGTH(4))
do_check_eq(this.readInt32(), 32);
// Command Details, Type-Length-Value
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
COMPREHENSIONTLV_FLAG_CR);
do_check_eq(pduHelper.readHexOctet(), 3);
do_check_eq(pduHelper.readHexOctet(), 0x01);
do_check_eq(pduHelper.readHexOctet(), STK_CMD_GET_INKEY);
do_check_eq(pduHelper.readHexOctet(), 0x04);
// Device Identifies, Type-Length-Value(Source ID-Destination ID)
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID);
do_check_eq(pduHelper.readHexOctet(), 2);
do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_ME);
do_check_eq(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM);
// Result
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT |
COMPREHENSIONTLV_FLAG_CR);
do_check_eq(pduHelper.readHexOctet(), 1);
do_check_eq(pduHelper.readHexOctet(), STK_RESULT_OK);
// Yes/No response
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING |
COMPREHENSIONTLV_FLAG_CR);
do_check_eq(pduHelper.readHexOctet(), 2);
do_check_eq(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_8BIT);
do_check_eq(pduHelper.readHexOctet(), isYesNo ? 0x01 : 0x00);
run_next_test();
};
let response = {
command: {
commandNumber: 0x01,
typeOfCommand: STK_CMD_GET_INKEY,
commandQualifier: 0x04,
options: {
isYesNoRequested: true
}
},
isYesNo: isYesNo,
resultCode: STK_RESULT_OK
};
context.RIL.sendStkTerminalResponse(response);
};
// Test "Yes" response
do_test(true);
// Test "No" response
do_test(false);
});
// Test ComprehensionTlvHelper
/**

View File

@ -6,23 +6,37 @@
#include "Principal.h"
#include "jsapi.h"
#include "mozilla/Assertions.h"
BEGIN_WORKERS_NAMESPACE
JSPrincipals*
GetWorkerPrincipal()
{
static Atomic<bool> sInitialized(false);
static JSPrincipals sPrincipal;
bool isInitialized = sInitialized.exchange(true);
if (!isInitialized) {
sPrincipal.refcount = 1;
/*
* To make sure the the principals refcount is initialized to one, atomically
* increment it on every pass though this function. If we discover this wasn't
* the first time, decrement it again. This avoids the need for
* synchronization.
*/
int32_t prevRefcount = sPrincipal.refcount++;
if (prevRefcount > 0) {
--sPrincipal.refcount;
} else {
#ifdef DEBUG
sPrincipal.debugToken = kJSPrincipalsDebugToken;
#endif
}
return &sPrincipal;
}
void
DestroyWorkerPrincipals(JSPrincipals* aPrincipals)
{
MOZ_ASSERT_UNREACHABLE("Worker principals refcount should never fall below one");
}
END_WORKERS_NAMESPACE

View File

@ -13,6 +13,9 @@ BEGIN_WORKERS_NAMESPACE
JSPrincipals*
GetWorkerPrincipal();
void
DestroyWorkerPrincipals(JSPrincipals* aPrincipals);
END_WORKERS_NAMESPACE
#endif /* mozilla_dom_workers_principal_h__ */

View File

@ -61,6 +61,7 @@
#include "nsThreadManager.h"
#endif
#include "Principal.h"
#include "ServiceWorker.h"
#include "SharedWorker.h"
#include "WorkerPrivate.h"
@ -852,6 +853,7 @@ public:
WORKER_DEFAULT_NURSERY_SIZE),
mWorkerPrivate(aWorkerPrivate)
{
JS_InitDestroyPrincipalsCallback(Runtime(), DestroyWorkerPrincipals);
}
~WorkerJSRuntime()

View File

@ -351,9 +351,10 @@ ConvertOmxYUVFormatToRGB565(android::sp<GraphicBuffer>& aBuffer,
return BAD_VALUE;
}
uint32_t pixelStride = aMappedSurface->mStride/gfx::BytesPerPixel(gfx::SurfaceFormat::R5G6B5);
rv = colorConverter.convert(buffer, width, height,
0, 0, width - 1, height - 1 /* source crop */,
aMappedSurface->mData, width, height,
aMappedSurface->mData, pixelStride, height,
0, 0, width - 1, height - 1 /* dest crop */);
if (rv) {
NS_WARNING("OMX color conversion failed");

View File

@ -31,7 +31,7 @@ static inline float sk_float_pow(float base, float exp) {
static inline float sk_float_copysign(float x, float y) {
// c++11 contains a 'float copysign(float, float)' function in <cmath>.
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#if (!defined(_MSC_VER) && __cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
return copysign(x, y);
// Posix has demanded 'float copysignf(float, float)' (from C99) since Issue 6.

View File

@ -438,7 +438,7 @@ ComputeColorMatrix(uint32_t aColorMatrixType, const nsTArray<float>& aValues,
aOutMatrix[5] = lumR - lumR * c + hueRotateR * s;
aOutMatrix[6] = lumG + oneMinusLumG * c + hueRotateG * s;
aOutMatrix[7] = lumB - oneMinusLumB * c - hueRotateB * s;
aOutMatrix[7] = lumB - lumB * c - hueRotateB * s;
aOutMatrix[10] = lumR - lumR * c - oneMinusLumR * s;
aOutMatrix[11] = lumG - lumG * c + lumG * s;

View File

@ -586,20 +586,13 @@ gfxContext::PixelSnappedRectangleAndSetPattern(const gfxRect& rect,
void
gfxContext::SetAntialiasMode(AntialiasMode mode)
{
if (mode == MODE_ALIASED) {
CurrentState().aaMode = gfx::AntialiasMode::NONE;
} else if (mode == MODE_COVERAGE) {
CurrentState().aaMode = gfx::AntialiasMode::SUBPIXEL;
}
CurrentState().aaMode = mode;
}
gfxContext::AntialiasMode
AntialiasMode
gfxContext::CurrentAntialiasMode() const
{
if (CurrentState().aaMode == gfx::AntialiasMode::NONE) {
return MODE_ALIASED;
}
return MODE_COVERAGE;
return CurrentState().aaMode;
}
void

View File

@ -529,17 +529,8 @@ public:
void SetOperator(GraphicsOperator op);
GraphicsOperator CurrentOperator() const;
/**
* MODE_ALIASED means that only pixels whose centers are in the drawn area
* should be modified, and they should be modified to take the value drawn
* at the pixel center.
*/
enum AntialiasMode {
MODE_ALIASED,
MODE_COVERAGE
};
void SetAntialiasMode(AntialiasMode mode);
AntialiasMode CurrentAntialiasMode() const;
void SetAntialiasMode(mozilla::gfx::AntialiasMode mode);
mozilla::gfx::AntialiasMode CurrentAntialiasMode() const;
/**
** Clipping

View File

@ -93,12 +93,10 @@ gfxSurfaceDrawable::DrawInternal(gfxContext* aContext,
dt->ClearRect(fillRect);
dt->FillRect(fillRect, pattern);
} else {
CompositionOp op = CompositionOpForOp(aContext->CurrentOperator());
AntialiasMode aaMode =
aContext->CurrentAntialiasMode() == gfxContext::MODE_ALIASED ?
AntialiasMode::NONE :
AntialiasMode::SUBPIXEL;
dt->FillRect(fillRect, pattern, DrawOptions(aOpacity, op, aaMode));
dt->FillRect(fillRect, pattern,
DrawOptions(aOpacity,
CompositionOpForOp(aContext->CurrentOperator()),
aContext->CurrentAntialiasMode()));
}
}

View File

@ -47,12 +47,12 @@ gfxPattern::gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0,
}
// Azure
gfxPattern::gfxPattern(SourceSurface *aSurface, const Matrix &aTransform)
: mTransform(aTransform)
gfxPattern::gfxPattern(SourceSurface *aSurface, const Matrix &aPatternToUserSpace)
: mPatternToUserSpace(aPatternToUserSpace)
, mExtend(EXTEND_NONE)
{
mGfxPattern = new (mSurfacePattern.addr())
SurfacePattern(aSurface, ToExtendMode(mExtend), aTransform,
SurfacePattern(aSurface, ToExtendMode(mExtend), Matrix(), // matrix is overridden in GetPattern()
mozilla::gfx::Filter::GOOD);
}
@ -100,13 +100,13 @@ gfxPattern::CacheColorStops(DrawTarget *aDT)
}
void
gfxPattern::SetMatrix(const gfxMatrix& matrix)
gfxPattern::SetMatrix(const gfxMatrix& aPatternToUserSpace)
{
mTransform = ToMatrix(matrix);
mPatternToUserSpace = ToMatrix(aPatternToUserSpace);
// Cairo-pattern matrices specify the conversion from DrawTarget to pattern
// space. Azure pattern matrices specify the conversion from pattern to
// DrawTarget space.
mTransform.Invert();
mPatternToUserSpace.Invert();
}
gfxMatrix
@ -114,7 +114,7 @@ gfxPattern::GetMatrix() const
{
// invert at the higher precision of gfxMatrix
// cause we need to convert at some point anyways
gfxMatrix mat = ThebesMatrix(mTransform);
gfxMatrix mat = ThebesMatrix(mPatternToUserSpace);
mat.Invert();
return mat;
}
@ -122,12 +122,33 @@ gfxPattern::GetMatrix() const
gfxMatrix
gfxPattern::GetInverseMatrix() const
{
return ThebesMatrix(mTransform);
return ThebesMatrix(mPatternToUserSpace);
}
Pattern*
gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform)
gfxPattern::GetPattern(DrawTarget *aTarget,
Matrix *aOriginalUserToDevice)
{
Matrix patternToUser = mPatternToUserSpace;
if (aOriginalUserToDevice &&
*aOriginalUserToDevice != aTarget->GetTransform()) {
// mPatternToUserSpace maps from pattern space to the original user space,
// but aTarget now has a transform to a different user space. In order for
// the Pattern* that we return to be usable in aTarget's new user space we
// need the Pattern's mMatrix to be the transform from pattern space to
// aTarget's -new- user space. That transform is equivalent to the
// transform from pattern space to original user space (patternToUser),
// multiplied by the transform from original user space to device space,
// multiplied by the transform from device space to current user space.
Matrix deviceToCurrentUser = aTarget->GetTransform();
deviceToCurrentUser.Invert();
patternToUser = patternToUser * *aOriginalUserToDevice * deviceToCurrentUser;
}
patternToUser.NudgeToIntegers();
if (!mStops &&
!mStopsList.IsEmpty()) {
mStops = aTarget->CreateGradientStops(mStopsList.Elements(),
@ -135,18 +156,17 @@ gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform)
ToExtendMode(mExtend));
}
Matrix* matrix = nullptr;
switch (mGfxPattern->GetType()) {
case PatternType::SURFACE:
matrix = &mSurfacePattern.addr()->mMatrix;
mSurfacePattern.addr()->mMatrix = patternToUser;
mSurfacePattern.addr()->mExtendMode = ToExtendMode(mExtend);
break;
case PatternType::LINEAR_GRADIENT:
matrix = &mLinearGradientPattern.addr()->mMatrix;
mLinearGradientPattern.addr()->mMatrix = patternToUser;
mLinearGradientPattern.addr()->mStops = mStops;
break;
case PatternType::RADIAL_GRADIENT:
matrix = &mRadialGradientPattern.addr()->mMatrix;
mRadialGradientPattern.addr()->mMatrix = patternToUser;
mRadialGradientPattern.addr()->mStops = mStops;
break;
default:
@ -154,15 +174,6 @@ gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform)
break;
}
if (matrix) {
*matrix = mTransform;
if (aPatternTransform) {
AdjustTransformForPattern(*matrix,
aTarget->GetTransform(),
aPatternTransform);
}
}
return mGfxPattern;
}
@ -233,29 +244,3 @@ gfxPattern::CairoStatus()
{
return CAIRO_STATUS_SUCCESS;
}
void
gfxPattern::AdjustTransformForPattern(Matrix &aPatternTransform,
const Matrix &aCurrentTransform,
const Matrix *aOriginalTransform)
{
aPatternTransform.Invert();
if (!aOriginalTransform) {
// User space is unchanged, so to get from pattern space to user space,
// just invert the cairo matrix.
aPatternTransform.NudgeToIntegers();
return;
}
// aPatternTransform now maps from pattern space to the user space defined
// by *aOriginalTransform.
Matrix mat = aCurrentTransform;
mat.Invert();
// mat maps from device space to current user space
// First, transform from pattern space to original user space. Then transform
// from original user space to device space. Then transform from
// device space to current user space.
aPatternTransform = aPatternTransform * *aOriginalTransform * mat;
aPatternTransform.NudgeToIntegers();
}

View File

@ -32,7 +32,7 @@ public:
gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0,
gfxFloat cx1, gfxFloat cy1, gfxFloat radius1); // radial
gfxPattern(mozilla::gfx::SourceSurface *aSurface,
const mozilla::gfx::Matrix &aTransform); // Azure
const mozilla::gfx::Matrix &aPatternToUserSpace);
void AddColorStop(gfxFloat offset, const gfxRGBA& c);
void SetColorStops(mozilla::gfx::GradientStops* aStops);
@ -52,7 +52,7 @@ public:
* to the current transform.
*/
mozilla::gfx::Pattern *GetPattern(mozilla::gfx::DrawTarget *aTarget,
mozilla::gfx::Matrix *aPatternTransform = nullptr);
mozilla::gfx::Matrix *aOriginalUserToDevice = nullptr);
bool IsOpaque();
enum GraphicsExtend {
@ -97,21 +97,6 @@ private:
// Private destructor, to discourage deletion outside of Release():
~gfxPattern();
/**
* aPatternTransform is the cairo pattern transform --- from user space at
* the time the pattern was set, to pattern space.
* aCurrentTransform is the DrawTarget's CTM --- from user space to device
* space.
* aOriginalTransform, if non-null, is the DrawTarget's TM when
* aPatternTransform was set --- user space to device space. If null, then
* the DrawTarget's CTM is the same as the TM when aPatternTransfrom was set.
* This function sets aPatternTransform to the Azure pattern transform ---
* from pattern space to current DrawTarget user space.
*/
void AdjustTransformForPattern(mozilla::gfx::Matrix &aPatternTransform,
const mozilla::gfx::Matrix &aCurrentTransform,
const mozilla::gfx::Matrix *aOriginalTransform);
union {
mozilla::AlignedStorage2<mozilla::gfx::ColorPattern> mColorPattern;
mozilla::AlignedStorage2<mozilla::gfx::LinearGradientPattern> mLinearGradientPattern;
@ -122,7 +107,7 @@ private:
mozilla::gfx::Pattern *mGfxPattern;
mozilla::RefPtr<mozilla::gfx::SourceSurface> mSourceSurface;
mozilla::gfx::Matrix mTransform;
mozilla::gfx::Matrix mPatternToUserSpace;
mozilla::RefPtr<mozilla::gfx::GradientStops> mStops;
nsTArray<mozilla::gfx::GradientStop> mStopsList;
GraphicsExtend mExtend;

View File

@ -90,7 +90,7 @@ of values.
nsIUGenCategory::nsUGenCategory sDetailedToGeneralCategory[] = {
/*
* The order here corresponds to the HB_UNICODE_GENERAL_CATEGORY_* constants
* of the hb_unicode_general_category_t enum in gfx/harfbuzz/src/hb-common.h.
* of the hb_unicode_general_category_t enum in gfx/harfbuzz/src/hb-unicode.h.
*/
/* CONTROL */ nsIUGenCategory::kOther,
/* FORMAT */ nsIUGenCategory::kOther,

View File

@ -24,6 +24,8 @@ struct JSPrincipals {
uint32_t debugToken;
#endif
JSPrincipals() : refcount(0) {}
void setDebugToken(uint32_t token) {
# ifdef JS_DEBUG
debugToken = token;

View File

@ -426,6 +426,29 @@ class Type
bool operator==(Type rhs) const { return which_ == rhs.which_; }
bool operator!=(Type rhs) const { return which_ != rhs.which_; }
inline bool operator<=(Type rhs) const {
switch (rhs.which_) {
case Type::Signed: return isSigned();
case Type::Unsigned: return isUnsigned();
case Type::Double: return isDouble();
case Type::Float: return isFloat();
case Type::Int32x4: return isInt32x4();
case Type::Float32x4: return isFloat32x4();
case Type::MaybeDouble: return isMaybeDouble();
case Type::MaybeFloat: return isMaybeFloat();
case Type::Floatish: return isFloatish();
case Type::Int: return isInt();
case Type::Intish: return isIntish();
case Type::Fixnum: return isFixnum();
case Type::Void: return isVoid();
}
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("unexpected this type");
}
bool isFixnum() const {
return which_ == Fixnum;
}
bool isSigned() const {
return which_ == Signed || which_ == Fixnum;
}
@ -535,6 +558,30 @@ class Type
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Invalid SIMD Type");
}
Type simdToCoercedScalarType() const {
JS_ASSERT(isSimd());
switch (which_) {
case Int32x4:
return Intish;
case Float32x4:
return Floatish;
// Scalar types
case Double:
case MaybeDouble:
case Float:
case MaybeFloat:
case Floatish:
case Fixnum:
case Int:
case Signed:
case Unsigned:
case Intish:
case Void:
break;
}
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Invalid SIMD Type");
}
AsmJSSimdType simdToSimdType() const {
JS_ASSERT(isSimd());
switch (which_) {
@ -2444,6 +2491,17 @@ class FunctionCompiler
return ins;
}
MDefinition *splatSimd(MDefinition *v, MIRType type)
{
if (inDeadCode())
return nullptr;
JS_ASSERT(IsSimdType(type));
MSimdSplatX4 *ins = MSimdSplatX4::New(alloc(), type, v);
curBlock_->add(ins);
return ins;
}
MDefinition *minMax(MDefinition *lhs, MDefinition *rhs, MIRType type, bool isMax) {
if (inDeadCode())
return nullptr;
@ -2620,18 +2678,6 @@ class FunctionCompiler
return ins;
}
template<typename T>
MDefinition *simdSplat(MDefinition *v, MIRType type)
{
if (inDeadCode())
return nullptr;
JS_ASSERT(IsSimdType(type));
T *ins = T::New(alloc(), type, v);
curBlock_->add(ins);
return ins;
}
/***************************************************************** Calls */
// The IonMonkey backend maintains a single stack offset (from the stack
@ -4696,161 +4742,127 @@ CheckMathBuiltinCall(FunctionCompiler &f, ParseNode *callNode, AsmJSMathBuiltinF
return true;
}
typedef Vector<MDefinition*, 4, SystemAllocPolicy> DefinitionVector;
namespace {
template<class CheckArgOp>
static bool
CheckUnarySimd(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Global *global,
MDefinition **def, Type *type)
CheckSimdCallArgs(FunctionCompiler &f, ParseNode *call, unsigned expectedArity,
const CheckArgOp &checkArg, DefinitionVector *defs)
{
unsigned numArgs = CallArgListLength(call);
if (numArgs != 1)
return f.failf(call, "expected 1 argument to unary arithmetic SIMD operation, got %u", numArgs);
if (numArgs != expectedArity)
return f.failf(call, "expected %u arguments to SIMD call, got %u", expectedArity, numArgs);
DefinitionVector &argDefs = *defs;
if (!argDefs.resize(numArgs))
return false;
ParseNode *arg = CallArgList(call);
MDefinition *argDef;
Type argType;
if (!CheckExpr(f, arg, &argDef, &argType))
return false;
for (size_t i = 0; i < numArgs; i++, arg = NextNode(arg)) {
MOZ_ASSERT(!!arg);
// For now, the only unary SIMD operation is splat(scalar).
MOZ_ASSERT(global->simdOperation() == AsmJSSimdOperation_splat);
switch (global->simdOperationType()) {
case AsmJSSimdType_int32x4:
if (!argType.isIntish())
return f.failf(arg, "%s is not a subtype of intish", argType.toChars());
break;
case AsmJSSimdType_float32x4:
if (!CheckFloatCoercionArg(f, arg, argType, argDef, &argDef))
return false;
break;
}
*type = global->simdOperationType();
*def = f.simdSplat<MSimdSplatX4>(argDef, type->toMIRType());
return true;
}
static bool
CheckBinarySimd(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Global *global,
MDefinition **def, Type *type)
{
unsigned numArgs = CallArgListLength(call);
if (numArgs != 2)
return f.failf(call, "expected 2 arguments to binary arithmetic SIMD operation, got %u", numArgs);
ParseNode *lhs = CallArgList(call);
ParseNode *rhs = NextNode(lhs);
MDefinition *lhsDef, *rhsDef;
Type lhsType, rhsType;
if (!CheckExpr(f, lhs, &lhsDef, &lhsType))
return false;
if (!CheckExpr(f, rhs, &rhsDef, &rhsType))
return false;
Type retType = global->simdOperationType();
if (lhsType != retType || rhsType != retType)
return f.failf(lhs, "arguments to SIMD binary op should both be %s", retType.toChars());
MIRType opType = retType.toMIRType();
switch (global->simdOperation()) {
case AsmJSSimdOperation_add:
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryArith::Add, opType);
*type = retType;
break;
case AsmJSSimdOperation_sub:
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryArith::Sub, opType);
*type = retType;
break;
case AsmJSSimdOperation_mul:
JS_ASSERT(!retType.isInt32x4());
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryArith::Mul, opType);
*type = retType;
break;
case AsmJSSimdOperation_div:
JS_ASSERT(!retType.isInt32x4());
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryArith::Div, opType);
*type = retType;
break;
case AsmJSSimdOperation_lessThan:
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryComp::lessThan);
*type = Type::Int32x4;
break;
case AsmJSSimdOperation_lessThanOrEqual:
JS_ASSERT(!retType.isInt32x4());
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryComp::lessThanOrEqual);
*type = Type::Int32x4;
break;
case AsmJSSimdOperation_equal:
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryComp::equal);
*type = Type::Int32x4;
break;
case AsmJSSimdOperation_notEqual:
JS_ASSERT(!retType.isInt32x4());
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryComp::notEqual);
*type = Type::Int32x4;
break;
case AsmJSSimdOperation_greaterThan:
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryComp::greaterThan);
*type = Type::Int32x4;
break;
case AsmJSSimdOperation_greaterThanOrEqual:
JS_ASSERT(!retType.isInt32x4());
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryComp::greaterThanOrEqual);
*type = Type::Int32x4;
break;
case AsmJSSimdOperation_and:
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryBitwise::and_, opType);
*type = retType;
break;
case AsmJSSimdOperation_or:
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryBitwise::or_, opType);
*type = retType;
break;
case AsmJSSimdOperation_xor:
*def = f.binarySimd(lhsDef, rhsDef, MSimdBinaryBitwise::xor_, opType);
*type = retType;
break;
case AsmJSSimdOperation_splat:
case AsmJSSimdOperation_select:
MOZ_CRASH("unexpected SIMD binary operation");
Type argType;
if (!CheckExpr(f, arg, &argDefs[i], &argType))
return false;
if (!checkArg(f, arg, i, argType, &argDefs[i]))
return false;
}
return true;
}
static bool
CheckSimdSelect(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Global *global,
MDefinition **def, Type *type)
class CheckSimdScalarArgs
{
MOZ_ASSERT(global->simdOperation() == AsmJSSimdOperation_select);
Type formalType_;
unsigned numArgs = CallArgListLength(call);
if (numArgs != 3)
return f.failf(call, "expected 3 arguments to ternary SIMD operation, got %u", numArgs);
public:
explicit CheckSimdScalarArgs(Type t) : formalType_(t.simdToCoercedScalarType()) {}
ParseNode *mask = CallArgList(call);
ParseNode *lhs = NextNode(mask);
ParseNode *rhs = NextNode(lhs);
bool operator()(FunctionCompiler &f, ParseNode *arg, unsigned argIndex, Type actualType,
MDefinition **argDef) const
{
if (formalType_ == Type::Floatish)
return CheckFloatCoercionArg(f, arg, actualType, *argDef, argDef);
MDefinition *maskDef;
Type maskType;
if (!CheckExpr(f, mask, &maskDef, &maskType))
if (!(actualType <= formalType_)) {
return f.failf(arg, "%s is not a subtype of %s", actualType.toChars(),
formalType_.toChars());
}
return true;
}
};
class CheckSimdVectorArgs
{
Type formalType_;
public:
explicit CheckSimdVectorArgs(Type t) : formalType_(t) {}
bool operator()(FunctionCompiler &f, ParseNode *arg, unsigned argIndex, Type actualType,
MDefinition **argDef) const
{
if (!(actualType <= formalType_)) {
return f.failf(arg, "%s is not a subtype of %s", actualType.toChars(),
formalType_.toChars());
}
return true;
}
};
class CheckSimdSelectArgs
{
Type formalType_;
public:
explicit CheckSimdSelectArgs(Type t) : formalType_(t) {}
bool operator()(FunctionCompiler &f, ParseNode *arg, unsigned argIndex, Type actualType,
MDefinition **argDef) const
{
if (argIndex == 0) {
// First argument of select is an int32x4 mask.
if (!(actualType <= Type::Int32x4))
return f.failf(arg, "%s is not a subtype of Int32x4", actualType.toChars());
return true;
}
if (!(actualType <= formalType_)) {
return f.failf(arg, "%s is not a subtype of %s", actualType.toChars(),
formalType_.toChars());
}
return true;
}
};
} // anonymous namespace
template<class OpEnum>
static inline bool
CheckSimdBinary(FunctionCompiler &f, ParseNode *call, Type retType, OpEnum op, MDefinition **def,
Type *type)
{
DefinitionVector argDefs;
if (!CheckSimdCallArgs(f, call, 2, CheckSimdVectorArgs(retType), &argDefs))
return false;
if (maskType != Type::Int32x4)
return f.failf(mask, "%s is not a subtype of int32x4", maskType.toChars());
MDefinition *lhsDef, *rhsDef;
Type lhsType, rhsType;
if (!CheckExpr(f, lhs, &lhsDef, &lhsType))
return false;
if (!CheckExpr(f, rhs, &rhsDef, &rhsType))
return false;
Type retType = global->simdOperationType();
if (lhsType != retType || rhsType != retType)
return f.failf(mask, "last two arguments to SIMD ternary op should both be %s", retType.toChars());
*def = f.binarySimd(argDefs[0], argDefs[1], op, retType.toMIRType());
*type = retType;
*def = f.ternarySimd(maskDef, lhsDef, rhsDef, MSimdTernaryBitwise::select, retType.toMIRType());
return true;
}
template<>
inline bool
CheckSimdBinary<MSimdBinaryComp::Operation>(FunctionCompiler &f, ParseNode *call, Type retType,
MSimdBinaryComp::Operation op, MDefinition **def,
Type *type)
{
DefinitionVector argDefs;
if (!CheckSimdCallArgs(f, call, 2, CheckSimdVectorArgs(retType), &argDefs))
return false;
*def = f.binarySimd(argDefs[0], argDefs[1], op);
*type = Type::Int32x4;
return true;
}
@ -4858,26 +4870,58 @@ static bool
CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Global *global,
MDefinition **def, Type *type)
{
JS_ASSERT(global->isSimdOperation());
MOZ_ASSERT(global->isSimdOperation());
Type retType = global->simdOperationType();
switch (global->simdOperation()) {
case AsmJSSimdOperation_splat:
return CheckUnarySimd(f, call, global, def, type);
case AsmJSSimdOperation_add:
return CheckSimdBinary(f, call, retType, MSimdBinaryArith::Add, def, type);
case AsmJSSimdOperation_sub:
return CheckSimdBinary(f, call, retType, MSimdBinaryArith::Sub, def, type);
case AsmJSSimdOperation_mul:
return CheckSimdBinary(f, call, retType, MSimdBinaryArith::Mul, def, type);
case AsmJSSimdOperation_div:
return CheckSimdBinary(f, call, retType, MSimdBinaryArith::Div, def, type);
case AsmJSSimdOperation_lessThan:
return CheckSimdBinary(f, call, retType, MSimdBinaryComp::lessThan, def, type);
case AsmJSSimdOperation_lessThanOrEqual:
return CheckSimdBinary(f, call, retType, MSimdBinaryComp::lessThanOrEqual, def, type);
case AsmJSSimdOperation_equal:
return CheckSimdBinary(f, call, retType, MSimdBinaryComp::equal, def, type);
case AsmJSSimdOperation_notEqual:
return CheckSimdBinary(f, call, retType, MSimdBinaryComp::notEqual, def, type);
case AsmJSSimdOperation_greaterThan:
return CheckSimdBinary(f, call, retType, MSimdBinaryComp::greaterThan, def, type);
case AsmJSSimdOperation_greaterThanOrEqual:
return CheckSimdBinary(f, call, retType, MSimdBinaryComp::greaterThanOrEqual, def, type);
case AsmJSSimdOperation_and:
return CheckSimdBinary(f, call, retType, MSimdBinaryBitwise::and_, def, type);
case AsmJSSimdOperation_or:
return CheckSimdBinary(f, call, retType, MSimdBinaryBitwise::or_, def, type);
case AsmJSSimdOperation_xor:
return CheckBinarySimd(f, call, global, def, type);
case AsmJSSimdOperation_select:
return CheckSimdSelect(f, call, global, def, type);
return CheckSimdBinary(f, call, retType, MSimdBinaryBitwise::xor_, def, type);
case AsmJSSimdOperation_splat: {
DefinitionVector defs;
if (!CheckSimdCallArgs(f, call, 1, CheckSimdScalarArgs(retType), &defs))
return false;
*def = f.splatSimd(defs[0], retType.toMIRType());
*type = retType;
return true;
}
case AsmJSSimdOperation_select: {
DefinitionVector defs;
if (!CheckSimdCallArgs(f, call, 3, CheckSimdSelectArgs(retType), &defs))
return false;
*def = f.ternarySimd(defs[0], defs[1], defs[2], MSimdTernaryBitwise::select,
retType.toMIRType());
*type = retType;
return true;
}
}
MOZ_CRASH("unexpected simd operation in CheckSimdOperationCall");
}
@ -4894,44 +4938,22 @@ CheckSimdCtorCall(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Gl
return CheckCoercionArg(f, argNode, coercion, def, type);
AsmJSSimdType simdType = global->simdCtorType();
unsigned numArgs = CallArgListLength(call);
unsigned length = SimdTypeToLength(simdType);
if (numArgs != length)
return f.failName(call, "invalid number of arguments in call to '%s'", CallCallee(call)->name());
Type retType = simdType;
Vector<MDefinition*, 4, SystemAllocPolicy> defs;
if (!defs.resize(length))
DefinitionVector defs;
if (!CheckSimdCallArgs(f, call, length, CheckSimdScalarArgs(retType), &defs))
return false;
argNode = CallArgList(call);
size_t i = 0;
for (; argNode; argNode = NextNode(argNode), ++i)
{
JS_ASSERT(i < length);
Type argType;
if (!CheckExpr(f, argNode, &defs[i], &argType))
return false;
switch (simdType) {
case AsmJSSimdType_int32x4:
if (!argType.isIntish())
return f.failf(argNode, "argument %d of Int32x4 ctor isn't a subtype of intish", i);
break;
case AsmJSSimdType_float32x4:
if (!CheckFloatCoercionArg(f, argNode, argType, defs[i], &defs[i]))
return false;
break;
}
}
JS_ASSERT(i == length);
*type = simdType;
// This code will need to be generalized when we handle float64x2
MOZ_ASSERT(length == 4);
MIRType opType = retType.toMIRType();
if (defs[1] == defs[0] && defs[2] == defs[0] && defs[3] == defs[0])
*def = f.simdSplat<MSimdSplatX4>(defs[0], type->toMIRType());
*def = f.splatSimd(defs[0], opType);
else
*def = f.constructSimd<MSimdValueX4>(defs[0], defs[1], defs[2], defs[3], type->toMIRType());
*def = f.constructSimd<MSimdValueX4>(defs[0], defs[1], defs[2], defs[3], opType);
*type = retType;
return true;
}

View File

@ -16,7 +16,6 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "builtin/SIMDShuffleMaskConstants.h"
#include "builtin/TypedObject.h"
#include "js/Value.h"
@ -372,6 +371,270 @@ const Class SIMDObject::class_ = {
nullptr
};
static JSConstIntegerSpec SHUFFLE_MASKS[] = {
{"XXXX", 0x0},
{"XXXY", 0x40},
{"XXXZ", 0x80},
{"XXXW", 0xC0},
{"XXYX", 0x10},
{"XXYY", 0x50},
{"XXYZ", 0x90},
{"XXYW", 0xD0},
{"XXZX", 0x20},
{"XXZY", 0x60},
{"XXZZ", 0xA0},
{"XXZW", 0xE0},
{"XXWX", 0x30},
{"XXWY", 0x70},
{"XXWZ", 0xB0},
{"XXWW", 0xF0},
{"XYXX", 0x4},
{"XYXY", 0x44},
{"XYXZ", 0x84},
{"XYXW", 0xC4},
{"XYYX", 0x14},
{"XYYY", 0x54},
{"XYYZ", 0x94},
{"XYYW", 0xD4},
{"XYZX", 0x24},
{"XYZY", 0x64},
{"XYZZ", 0xA4},
{"XYZW", 0xE4},
{"XYWX", 0x34},
{"XYWY", 0x74},
{"XYWZ", 0xB4},
{"XYWW", 0xF4},
{"XZXX", 0x8},
{"XZXY", 0x48},
{"XZXZ", 0x88},
{"XZXW", 0xC8},
{"XZYX", 0x18},
{"XZYY", 0x58},
{"XZYZ", 0x98},
{"XZYW", 0xD8},
{"XZZX", 0x28},
{"XZZY", 0x68},
{"XZZZ", 0xA8},
{"XZZW", 0xE8},
{"XZWX", 0x38},
{"XZWY", 0x78},
{"XZWZ", 0xB8},
{"XZWW", 0xF8},
{"XWXX", 0xC},
{"XWXY", 0x4C},
{"XWXZ", 0x8C},
{"XWXW", 0xCC},
{"XWYX", 0x1C},
{"XWYY", 0x5C},
{"XWYZ", 0x9C},
{"XWYW", 0xDC},
{"XWZX", 0x2C},
{"XWZY", 0x6C},
{"XWZZ", 0xAC},
{"XWZW", 0xEC},
{"XWWX", 0x3C},
{"XWWY", 0x7C},
{"XWWZ", 0xBC},
{"XWWW", 0xFC},
{"YXXX", 0x1},
{"YXXY", 0x41},
{"YXXZ", 0x81},
{"YXXW", 0xC1},
{"YXYX", 0x11},
{"YXYY", 0x51},
{"YXYZ", 0x91},
{"YXYW", 0xD1},
{"YXZX", 0x21},
{"YXZY", 0x61},
{"YXZZ", 0xA1},
{"YXZW", 0xE1},
{"YXWX", 0x31},
{"YXWY", 0x71},
{"YXWZ", 0xB1},
{"YXWW", 0xF1},
{"YYXX", 0x5},
{"YYXY", 0x45},
{"YYXZ", 0x85},
{"YYXW", 0xC5},
{"YYYX", 0x15},
{"YYYY", 0x55},
{"YYYZ", 0x95},
{"YYYW", 0xD5},
{"YYZX", 0x25},
{"YYZY", 0x65},
{"YYZZ", 0xA5},
{"YYZW", 0xE5},
{"YYWX", 0x35},
{"YYWY", 0x75},
{"YYWZ", 0xB5},
{"YYWW", 0xF5},
{"YZXX", 0x9},
{"YZXY", 0x49},
{"YZXZ", 0x89},
{"YZXW", 0xC9},
{"YZYX", 0x19},
{"YZYY", 0x59},
{"YZYZ", 0x99},
{"YZYW", 0xD9},
{"YZZX", 0x29},
{"YZZY", 0x69},
{"YZZZ", 0xA9},
{"YZZW", 0xE9},
{"YZWX", 0x39},
{"YZWY", 0x79},
{"YZWZ", 0xB9},
{"YZWW", 0xF9},
{"YWXX", 0xD},
{"YWXY", 0x4D},
{"YWXZ", 0x8D},
{"YWXW", 0xCD},
{"YWYX", 0x1D},
{"YWYY", 0x5D},
{"YWYZ", 0x9D},
{"YWYW", 0xDD},
{"YWZX", 0x2D},
{"YWZY", 0x6D},
{"YWZZ", 0xAD},
{"YWZW", 0xED},
{"YWWX", 0x3D},
{"YWWY", 0x7D},
{"YWWZ", 0xBD},
{"YWWW", 0xFD},
{"ZXXX", 0x2},
{"ZXXY", 0x42},
{"ZXXZ", 0x82},
{"ZXXW", 0xC2},
{"ZXYX", 0x12},
{"ZXYY", 0x52},
{"ZXYZ", 0x92},
{"ZXYW", 0xD2},
{"ZXZX", 0x22},
{"ZXZY", 0x62},
{"ZXZZ", 0xA2},
{"ZXZW", 0xE2},
{"ZXWX", 0x32},
{"ZXWY", 0x72},
{"ZXWZ", 0xB2},
{"ZXWW", 0xF2},
{"ZYXX", 0x6},
{"ZYXY", 0x46},
{"ZYXZ", 0x86},
{"ZYXW", 0xC6},
{"ZYYX", 0x16},
{"ZYYY", 0x56},
{"ZYYZ", 0x96},
{"ZYYW", 0xD6},
{"ZYZX", 0x26},
{"ZYZY", 0x66},
{"ZYZZ", 0xA6},
{"ZYZW", 0xE6},
{"ZYWX", 0x36},
{"ZYWY", 0x76},
{"ZYWZ", 0xB6},
{"ZYWW", 0xF6},
{"ZZXX", 0xA},
{"ZZXY", 0x4A},
{"ZZXZ", 0x8A},
{"ZZXW", 0xCA},
{"ZZYX", 0x1A},
{"ZZYY", 0x5A},
{"ZZYZ", 0x9A},
{"ZZYW", 0xDA},
{"ZZZX", 0x2A},
{"ZZZY", 0x6A},
{"ZZZZ", 0xAA},
{"ZZZW", 0xEA},
{"ZZWX", 0x3A},
{"ZZWY", 0x7A},
{"ZZWZ", 0xBA},
{"ZZWW", 0xFA},
{"ZWXX", 0xE},
{"ZWXY", 0x4E},
{"ZWXZ", 0x8E},
{"ZWXW", 0xCE},
{"ZWYX", 0x1E},
{"ZWYY", 0x5E},
{"ZWYZ", 0x9E},
{"ZWYW", 0xDE},
{"ZWZX", 0x2E},
{"ZWZY", 0x6E},
{"ZWZZ", 0xAE},
{"ZWZW", 0xEE},
{"ZWWX", 0x3E},
{"ZWWY", 0x7E},
{"ZWWZ", 0xBE},
{"ZWWW", 0xFE},
{"WXXX", 0x3},
{"WXXY", 0x43},
{"WXXZ", 0x83},
{"WXXW", 0xC3},
{"WXYX", 0x13},
{"WXYY", 0x53},
{"WXYZ", 0x93},
{"WXYW", 0xD3},
{"WXZX", 0x23},
{"WXZY", 0x63},
{"WXZZ", 0xA3},
{"WXZW", 0xE3},
{"WXWX", 0x33},
{"WXWY", 0x73},
{"WXWZ", 0xB3},
{"WXWW", 0xF3},
{"WYXX", 0x7},
{"WYXY", 0x47},
{"WYXZ", 0x87},
{"WYXW", 0xC7},
{"WYYX", 0x17},
{"WYYY", 0x57},
{"WYYZ", 0x97},
{"WYYW", 0xD7},
{"WYZX", 0x27},
{"WYZY", 0x67},
{"WYZZ", 0xA7},
{"WYZW", 0xE7},
{"WYWX", 0x37},
{"WYWY", 0x77},
{"WYWZ", 0xB7},
{"WYWW", 0xF7},
{"WZXX", 0xB},
{"WZXY", 0x4B},
{"WZXZ", 0x8B},
{"WZXW", 0xCB},
{"WZYX", 0x1B},
{"WZYY", 0x5B},
{"WZYZ", 0x9B},
{"WZYW", 0xDB},
{"WZZX", 0x2B},
{"WZZY", 0x6B},
{"WZZZ", 0xAB},
{"WZZW", 0xEB},
{"WZWX", 0x3B},
{"WZWY", 0x7B},
{"WZWZ", 0xBB},
{"WZWW", 0xFB},
{"WWXX", 0xF},
{"WWXY", 0x4F},
{"WWXZ", 0x8F},
{"WWXW", 0xCF},
{"WWYX", 0x1F},
{"WWYY", 0x5F},
{"WWYZ", 0x9F},
{"WWYW", 0xDF},
{"WWZX", 0x2F},
{"WWZY", 0x6F},
{"WWZZ", 0xAF},
{"WWZW", 0xEF},
{"WWWX", 0x3F},
{"WWWY", 0x7F},
{"WWWZ", 0xBF},
{"WWWW", 0xFF},
{"XX", 0x0},
{"XY", 0x2},
{"YX", 0x1},
{"YY", 0x3},
{0,0}
};
JSObject *
SIMDObject::initClass(JSContext *cx, Handle<GlobalObject *> global)
{
@ -392,7 +655,8 @@ SIMDObject::initClass(JSContext *cx, Handle<GlobalObject *> global)
if (!SIMD)
return nullptr;
SET_ALL_SHUFFLE_MASKS;
if (!JS_DefineConstIntegers(cx, SIMD, SHUFFLE_MASKS))
return nullptr;
// float32x4
RootedObject float32x4Object(cx);

View File

@ -1,284 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef builtin_SIMDShuffleMaskConstants_h
#define builtin_SIMDShuffleMaskConstants_h
#define COMMON_PROPERTY_NAMES_MACRO(macro, mask, maskStr, value) macro(mask, mask, maskStr)
#define SET_SHUFFLE_MASK(macro, maskId, maskStr, value) \
{ \
RootedValue mask##maskId(cx, JS::Int32Value(value)); \
JSObject::defineProperty(cx, SIMD, cx->names().maskId, \
mask##maskId, nullptr, nullptr, \
JSPROP_READONLY | JSPROP_PERMANENT); \
}
#define SET_ALL_SHUFFLE_MASKS FOR_EACH_SIMD_SHUFFLE_MASK(SET_SHUFFLE_MASK, 0)
#define FOR_EACH_SIMD_SHUFFLE_MASK(macro, innerMacro) \
macro(innerMacro, XXXX, "XXXX", 0x0) \
macro(innerMacro, XXXY, "XXXY", 0x40) \
macro(innerMacro, XXXZ, "XXXZ", 0x80) \
macro(innerMacro, XXXW, "XXXW", 0xC0) \
macro(innerMacro, XXYX, "XXYX", 0x10) \
macro(innerMacro, XXYY, "XXYY", 0x50) \
macro(innerMacro, XXYZ, "XXYZ", 0x90) \
macro(innerMacro, XXYW, "XXYW", 0xD0) \
macro(innerMacro, XXZX, "XXZX", 0x20) \
macro(innerMacro, XXZY, "XXZY", 0x60) \
macro(innerMacro, XXZZ, "XXZZ", 0xA0) \
macro(innerMacro, XXZW, "XXZW", 0xE0) \
macro(innerMacro, XXWX, "XXWX", 0x30) \
macro(innerMacro, XXWY, "XXWY", 0x70) \
macro(innerMacro, XXWZ, "XXWZ", 0xB0) \
macro(innerMacro, XXWW, "XXWW", 0xF0) \
macro(innerMacro, XYXX, "XYXX", 0x4) \
macro(innerMacro, XYXY, "XYXY", 0x44) \
macro(innerMacro, XYXZ, "XYXZ", 0x84) \
macro(innerMacro, XYXW, "XYXW", 0xC4) \
macro(innerMacro, XYYX, "XYYX", 0x14) \
macro(innerMacro, XYYY, "XYYY", 0x54) \
macro(innerMacro, XYYZ, "XYYZ", 0x94) \
macro(innerMacro, XYYW, "XYYW", 0xD4) \
macro(innerMacro, XYZX, "XYZX", 0x24) \
macro(innerMacro, XYZY, "XYZY", 0x64) \
macro(innerMacro, XYZZ, "XYZZ", 0xA4) \
macro(innerMacro, XYZW, "XYZW", 0xE4) \
macro(innerMacro, XYWX, "XYWX", 0x34) \
macro(innerMacro, XYWY, "XYWY", 0x74) \
macro(innerMacro, XYWZ, "XYWZ", 0xB4) \
macro(innerMacro, XYWW, "XYWW", 0xF4) \
macro(innerMacro, XZXX, "XZXX", 0x8) \
macro(innerMacro, XZXY, "XZXY", 0x48) \
macro(innerMacro, XZXZ, "XZXZ", 0x88) \
macro(innerMacro, XZXW, "XZXW", 0xC8) \
macro(innerMacro, XZYX, "XZYX", 0x18) \
macro(innerMacro, XZYY, "XZYY", 0x58) \
macro(innerMacro, XZYZ, "XZYZ", 0x98) \
macro(innerMacro, XZYW, "XZYW", 0xD8) \
macro(innerMacro, XZZX, "XZZX", 0x28) \
macro(innerMacro, XZZY, "XZZY", 0x68) \
macro(innerMacro, XZZZ, "XZZZ", 0xA8) \
macro(innerMacro, XZZW, "XZZW", 0xE8) \
macro(innerMacro, XZWX, "XZWX", 0x38) \
macro(innerMacro, XZWY, "XZWY", 0x78) \
macro(innerMacro, XZWZ, "XZWZ", 0xB8) \
macro(innerMacro, XZWW, "XZWW", 0xF8) \
macro(innerMacro, XWXX, "XWXX", 0xC) \
macro(innerMacro, XWXY, "XWXY", 0x4C) \
macro(innerMacro, XWXZ, "XWXZ", 0x8C) \
macro(innerMacro, XWXW, "XWXW", 0xCC) \
macro(innerMacro, XWYX, "XWYX", 0x1C) \
macro(innerMacro, XWYY, "XWYY", 0x5C) \
macro(innerMacro, XWYZ, "XWYZ", 0x9C) \
macro(innerMacro, XWYW, "XWYW", 0xDC) \
macro(innerMacro, XWZX, "XWZX", 0x2C) \
macro(innerMacro, XWZY, "XWZY", 0x6C) \
macro(innerMacro, XWZZ, "XWZZ", 0xAC) \
macro(innerMacro, XWZW, "XWZW", 0xEC) \
macro(innerMacro, XWWX, "XWWX", 0x3C) \
macro(innerMacro, XWWY, "XWWY", 0x7C) \
macro(innerMacro, XWWZ, "XWWZ", 0xBC) \
macro(innerMacro, XWWW, "XWWW", 0xFC) \
macro(innerMacro, YXXX, "YXXX", 0x1) \
macro(innerMacro, YXXY, "YXXY", 0x41) \
macro(innerMacro, YXXZ, "YXXZ", 0x81) \
macro(innerMacro, YXXW, "YXXW", 0xC1) \
macro(innerMacro, YXYX, "YXYX", 0x11) \
macro(innerMacro, YXYY, "YXYY", 0x51) \
macro(innerMacro, YXYZ, "YXYZ", 0x91) \
macro(innerMacro, YXYW, "YXYW", 0xD1) \
macro(innerMacro, YXZX, "YXZX", 0x21) \
macro(innerMacro, YXZY, "YXZY", 0x61) \
macro(innerMacro, YXZZ, "YXZZ", 0xA1) \
macro(innerMacro, YXZW, "YXZW", 0xE1) \
macro(innerMacro, YXWX, "YXWX", 0x31) \
macro(innerMacro, YXWY, "YXWY", 0x71) \
macro(innerMacro, YXWZ, "YXWZ", 0xB1) \
macro(innerMacro, YXWW, "YXWW", 0xF1) \
macro(innerMacro, YYXX, "YYXX", 0x5) \
macro(innerMacro, YYXY, "YYXY", 0x45) \
macro(innerMacro, YYXZ, "YYXZ", 0x85) \
macro(innerMacro, YYXW, "YYXW", 0xC5) \
macro(innerMacro, YYYX, "YYYX", 0x15) \
macro(innerMacro, YYYY, "YYYY", 0x55) \
macro(innerMacro, YYYZ, "YYYZ", 0x95) \
macro(innerMacro, YYYW, "YYYW", 0xD5) \
macro(innerMacro, YYZX, "YYZX", 0x25) \
macro(innerMacro, YYZY, "YYZY", 0x65) \
macro(innerMacro, YYZZ, "YYZZ", 0xA5) \
macro(innerMacro, YYZW, "YYZW", 0xE5) \
macro(innerMacro, YYWX, "YYWX", 0x35) \
macro(innerMacro, YYWY, "YYWY", 0x75) \
macro(innerMacro, YYWZ, "YYWZ", 0xB5) \
macro(innerMacro, YYWW, "YYWW", 0xF5) \
macro(innerMacro, YZXX, "YZXX", 0x9) \
macro(innerMacro, YZXY, "YZXY", 0x49) \
macro(innerMacro, YZXZ, "YZXZ", 0x89) \
macro(innerMacro, YZXW, "YZXW", 0xC9) \
macro(innerMacro, YZYX, "YZYX", 0x19) \
macro(innerMacro, YZYY, "YZYY", 0x59) \
macro(innerMacro, YZYZ, "YZYZ", 0x99) \
macro(innerMacro, YZYW, "YZYW", 0xD9) \
macro(innerMacro, YZZX, "YZZX", 0x29) \
macro(innerMacro, YZZY, "YZZY", 0x69) \
macro(innerMacro, YZZZ, "YZZZ", 0xA9) \
macro(innerMacro, YZZW, "YZZW", 0xE9) \
macro(innerMacro, YZWX, "YZWX", 0x39) \
macro(innerMacro, YZWY, "YZWY", 0x79) \
macro(innerMacro, YZWZ, "YZWZ", 0xB9) \
macro(innerMacro, YZWW, "YZWW", 0xF9) \
macro(innerMacro, YWXX, "YWXX", 0xD) \
macro(innerMacro, YWXY, "YWXY", 0x4D) \
macro(innerMacro, YWXZ, "YWXZ", 0x8D) \
macro(innerMacro, YWXW, "YWXW", 0xCD) \
macro(innerMacro, YWYX, "YWYX", 0x1D) \
macro(innerMacro, YWYY, "YWYY", 0x5D) \
macro(innerMacro, YWYZ, "YWYZ", 0x9D) \
macro(innerMacro, YWYW, "YWYW", 0xDD) \
macro(innerMacro, YWZX, "YWZX", 0x2D) \
macro(innerMacro, YWZY, "YWZY", 0x6D) \
macro(innerMacro, YWZZ, "YWZZ", 0xAD) \
macro(innerMacro, YWZW, "YWZW", 0xED) \
macro(innerMacro, YWWX, "YWWX", 0x3D) \
macro(innerMacro, YWWY, "YWWY", 0x7D) \
macro(innerMacro, YWWZ, "YWWZ", 0xBD) \
macro(innerMacro, YWWW, "YWWW", 0xFD) \
macro(innerMacro, ZXXX, "ZXXX", 0x2) \
macro(innerMacro, ZXXY, "ZXXY", 0x42) \
macro(innerMacro, ZXXZ, "ZXXZ", 0x82) \
macro(innerMacro, ZXXW, "ZXXW", 0xC2) \
macro(innerMacro, ZXYX, "ZXYX", 0x12) \
macro(innerMacro, ZXYY, "ZXYY", 0x52) \
macro(innerMacro, ZXYZ, "ZXYZ", 0x92) \
macro(innerMacro, ZXYW, "ZXYW", 0xD2) \
macro(innerMacro, ZXZX, "ZXZX", 0x22) \
macro(innerMacro, ZXZY, "ZXZY", 0x62) \
macro(innerMacro, ZXZZ, "ZXZZ", 0xA2) \
macro(innerMacro, ZXZW, "ZXZW", 0xE2) \
macro(innerMacro, ZXWX, "ZXWX", 0x32) \
macro(innerMacro, ZXWY, "ZXWY", 0x72) \
macro(innerMacro, ZXWZ, "ZXWZ", 0xB2) \
macro(innerMacro, ZXWW, "ZXWW", 0xF2) \
macro(innerMacro, ZYXX, "ZYXX", 0x6) \
macro(innerMacro, ZYXY, "ZYXY", 0x46) \
macro(innerMacro, ZYXZ, "ZYXZ", 0x86) \
macro(innerMacro, ZYXW, "ZYXW", 0xC6) \
macro(innerMacro, ZYYX, "ZYYX", 0x16) \
macro(innerMacro, ZYYY, "ZYYY", 0x56) \
macro(innerMacro, ZYYZ, "ZYYZ", 0x96) \
macro(innerMacro, ZYYW, "ZYYW", 0xD6) \
macro(innerMacro, ZYZX, "ZYZX", 0x26) \
macro(innerMacro, ZYZY, "ZYZY", 0x66) \
macro(innerMacro, ZYZZ, "ZYZZ", 0xA6) \
macro(innerMacro, ZYZW, "ZYZW", 0xE6) \
macro(innerMacro, ZYWX, "ZYWX", 0x36) \
macro(innerMacro, ZYWY, "ZYWY", 0x76) \
macro(innerMacro, ZYWZ, "ZYWZ", 0xB6) \
macro(innerMacro, ZYWW, "ZYWW", 0xF6) \
macro(innerMacro, ZZXX, "ZZXX", 0xA) \
macro(innerMacro, ZZXY, "ZZXY", 0x4A) \
macro(innerMacro, ZZXZ, "ZZXZ", 0x8A) \
macro(innerMacro, ZZXW, "ZZXW", 0xCA) \
macro(innerMacro, ZZYX, "ZZYX", 0x1A) \
macro(innerMacro, ZZYY, "ZZYY", 0x5A) \
macro(innerMacro, ZZYZ, "ZZYZ", 0x9A) \
macro(innerMacro, ZZYW, "ZZYW", 0xDA) \
macro(innerMacro, ZZZX, "ZZZX", 0x2A) \
macro(innerMacro, ZZZY, "ZZZY", 0x6A) \
macro(innerMacro, ZZZZ, "ZZZZ", 0xAA) \
macro(innerMacro, ZZZW, "ZZZW", 0xEA) \
macro(innerMacro, ZZWX, "ZZWX", 0x3A) \
macro(innerMacro, ZZWY, "ZZWY", 0x7A) \
macro(innerMacro, ZZWZ, "ZZWZ", 0xBA) \
macro(innerMacro, ZZWW, "ZZWW", 0xFA) \
macro(innerMacro, ZWXX, "ZWXX", 0xE) \
macro(innerMacro, ZWXY, "ZWXY", 0x4E) \
macro(innerMacro, ZWXZ, "ZWXZ", 0x8E) \
macro(innerMacro, ZWXW, "ZWXW", 0xCE) \
macro(innerMacro, ZWYX, "ZWYX", 0x1E) \
macro(innerMacro, ZWYY, "ZWYY", 0x5E) \
macro(innerMacro, ZWYZ, "ZWYZ", 0x9E) \
macro(innerMacro, ZWYW, "ZWYW", 0xDE) \
macro(innerMacro, ZWZX, "ZWZX", 0x2E) \
macro(innerMacro, ZWZY, "ZWZY", 0x6E) \
macro(innerMacro, ZWZZ, "ZWZZ", 0xAE) \
macro(innerMacro, ZWZW, "ZWZW", 0xEE) \
macro(innerMacro, ZWWX, "ZWWX", 0x3E) \
macro(innerMacro, ZWWY, "ZWWY", 0x7E) \
macro(innerMacro, ZWWZ, "ZWWZ", 0xBE) \
macro(innerMacro, ZWWW, "ZWWW", 0xFE) \
macro(innerMacro, WXXX, "WXXX", 0x3) \
macro(innerMacro, WXXY, "WXXY", 0x43) \
macro(innerMacro, WXXZ, "WXXZ", 0x83) \
macro(innerMacro, WXXW, "WXXW", 0xC3) \
macro(innerMacro, WXYX, "WXYX", 0x13) \
macro(innerMacro, WXYY, "WXYY", 0x53) \
macro(innerMacro, WXYZ, "WXYZ", 0x93) \
macro(innerMacro, WXYW, "WXYW", 0xD3) \
macro(innerMacro, WXZX, "WXZX", 0x23) \
macro(innerMacro, WXZY, "WXZY", 0x63) \
macro(innerMacro, WXZZ, "WXZZ", 0xA3) \
macro(innerMacro, WXZW, "WXZW", 0xE3) \
macro(innerMacro, WXWX, "WXWX", 0x33) \
macro(innerMacro, WXWY, "WXWY", 0x73) \
macro(innerMacro, WXWZ, "WXWZ", 0xB3) \
macro(innerMacro, WXWW, "WXWW", 0xF3) \
macro(innerMacro, WYXX, "WYXX", 0x7) \
macro(innerMacro, WYXY, "WYXY", 0x47) \
macro(innerMacro, WYXZ, "WYXZ", 0x87) \
macro(innerMacro, WYXW, "WYXW", 0xC7) \
macro(innerMacro, WYYX, "WYYX", 0x17) \
macro(innerMacro, WYYY, "WYYY", 0x57) \
macro(innerMacro, WYYZ, "WYYZ", 0x97) \
macro(innerMacro, WYYW, "WYYW", 0xD7) \
macro(innerMacro, WYZX, "WYZX", 0x27) \
macro(innerMacro, WYZY, "WYZY", 0x67) \
macro(innerMacro, WYZZ, "WYZZ", 0xA7) \
macro(innerMacro, WYZW, "WYZW", 0xE7) \
macro(innerMacro, WYWX, "WYWX", 0x37) \
macro(innerMacro, WYWY, "WYWY", 0x77) \
macro(innerMacro, WYWZ, "WYWZ", 0xB7) \
macro(innerMacro, WYWW, "WYWW", 0xF7) \
macro(innerMacro, WZXX, "WZXX", 0xB) \
macro(innerMacro, WZXY, "WZXY", 0x4B) \
macro(innerMacro, WZXZ, "WZXZ", 0x8B) \
macro(innerMacro, WZXW, "WZXW", 0xCB) \
macro(innerMacro, WZYX, "WZYX", 0x1B) \
macro(innerMacro, WZYY, "WZYY", 0x5B) \
macro(innerMacro, WZYZ, "WZYZ", 0x9B) \
macro(innerMacro, WZYW, "WZYW", 0xDB) \
macro(innerMacro, WZZX, "WZZX", 0x2B) \
macro(innerMacro, WZZY, "WZZY", 0x6B) \
macro(innerMacro, WZZZ, "WZZZ", 0xAB) \
macro(innerMacro, WZZW, "WZZW", 0xEB) \
macro(innerMacro, WZWX, "WZWX", 0x3B) \
macro(innerMacro, WZWY, "WZWY", 0x7B) \
macro(innerMacro, WZWZ, "WZWZ", 0xBB) \
macro(innerMacro, WZWW, "WZWW", 0xFB) \
macro(innerMacro, WWXX, "WWXX", 0xF) \
macro(innerMacro, WWXY, "WWXY", 0x4F) \
macro(innerMacro, WWXZ, "WWXZ", 0x8F) \
macro(innerMacro, WWXW, "WWXW", 0xCF) \
macro(innerMacro, WWYX, "WWYX", 0x1F) \
macro(innerMacro, WWYY, "WWYY", 0x5F) \
macro(innerMacro, WWYZ, "WWYZ", 0x9F) \
macro(innerMacro, WWYW, "WWYW", 0xDF) \
macro(innerMacro, WWZX, "WWZX", 0x2F) \
macro(innerMacro, WWZY, "WWZY", 0x6F) \
macro(innerMacro, WWZZ, "WWZZ", 0xAF) \
macro(innerMacro, WWZW, "WWZW", 0xEF) \
macro(innerMacro, WWWX, "WWWX", 0x3F) \
macro(innerMacro, WWWY, "WWWY", 0x7F) \
macro(innerMacro, WWWZ, "WWWZ", 0xBF) \
macro(innerMacro, WWWW, "WWWW", 0xFF) \
macro(innerMacro, XX, "XX", 0x0) \
macro(innerMacro, XY, "XY", 0x2) \
macro(innerMacro, YX, "YX", 0x1) \
macro(innerMacro, YY, "YY", 0x3)
#endif

View File

@ -459,7 +459,7 @@ namespace CDataFinalizer {
*
* Note that the jsval is actually not recorded, but converted back from C.
*/
static bool GetValue(JSContext *cx, JSObject *obj, jsval *result);
static bool GetValue(JSContext *cx, JSObject *obj, MutableHandleValue result);
static JSObject* GetCData(JSContext *cx, JSObject *obj);
}
@ -1717,7 +1717,7 @@ jsvalToInteger(JSContext* cx, jsval val, IntegerType* result)
if (CDataFinalizer::IsCDataFinalizer(obj)) {
RootedValue innerData(cx);
if (!CDataFinalizer::GetValue(cx, obj, innerData.address())) {
if (!CDataFinalizer::GetValue(cx, obj, &innerData)) {
return false; // Nothing to convert
}
return jsvalToInteger(cx, innerData, result);
@ -1908,7 +1908,7 @@ jsvalToBigInteger(JSContext* cx,
if (CDataFinalizer::IsCDataFinalizer(obj)) {
RootedValue innerData(cx);
if (!CDataFinalizer::GetValue(cx, obj, innerData.address())) {
if (!CDataFinalizer::GetValue(cx, obj, &innerData)) {
return false; // Nothing to convert
}
return jsvalToBigInteger(cx, innerData, allowString, result);
@ -1973,14 +1973,14 @@ jsidToSize(JSContext* cx, jsid val, bool allowString, size_t* result)
// Implicitly convert a size value to a jsval, ensuring that the size_t value
// fits in a double.
static bool
SizeTojsval(JSContext* cx, size_t size, jsval* result)
SizeTojsval(JSContext* cx, size_t size, MutableHandleValue result)
{
if (Convert<size_t>(double(size)) != size) {
JS_ReportError(cx, "size overflow");
return false;
}
*result = JS_NumberValue(double(size));
result.setNumber(double(size));
return true;
}
@ -2125,7 +2125,7 @@ ConvertToJS(JSContext* cx,
void* data,
bool wantPrimitive,
bool ownResult,
jsval* result)
MutableHandleValue result)
{
JS_ASSERT(!parentObj || CData::IsCData(parentObj));
JS_ASSERT(!parentObj || !ownResult);
@ -2135,18 +2135,18 @@ ConvertToJS(JSContext* cx,
switch (typeCode) {
case TYPE_void_t:
*result = JSVAL_VOID;
result.setUndefined();
break;
case TYPE_bool:
*result = *static_cast<bool*>(data) ? JSVAL_TRUE : JSVAL_FALSE;
result.setBoolean(*static_cast<bool*>(data));
break;
#define DEFINE_INT_TYPE(name, type, ffiType) \
case TYPE_##name: { \
type value = *static_cast<type*>(data); \
if (sizeof(type) < 4) \
*result = INT_TO_JSVAL(int32_t(value)); \
result.setInt32(int32_t(value)); \
else \
*result = JS_NumberValue(double(value)); \
result.setDouble(double(value)); \
break; \
}
#define DEFINE_WRAPPED_INT_TYPE(name, type, ffiType) \
@ -2172,20 +2172,20 @@ ConvertToJS(JSContext* cx,
!NumericLimits<type>::is_signed); \
if (!obj) \
return false; \
*result = OBJECT_TO_JSVAL(obj); \
result.setObject(*obj); \
break; \
}
#define DEFINE_FLOAT_TYPE(name, type, ffiType) \
case TYPE_##name: { \
type value = *static_cast<type*>(data); \
*result = JS_NumberValue(double(value)); \
result.setDouble(double(value)); \
break; \
}
#define DEFINE_CHAR_TYPE(name, type, ffiType) \
case TYPE_##name: \
/* Convert to an integer. We have no idea what character encoding to */ \
/* use, if any. */ \
*result = INT_TO_JSVAL(*static_cast<type*>(data)); \
result.setInt32(*static_cast<type*>(data)); \
break;
#include "ctypes/typedefs.h"
case TYPE_char16_t: {
@ -2194,7 +2194,7 @@ ConvertToJS(JSContext* cx,
if (!str)
return false;
*result = STRING_TO_JSVAL(str);
result.setString(str);
break;
}
case TYPE_pointer:
@ -2211,7 +2211,7 @@ ConvertToJS(JSContext* cx,
if (!obj)
return false;
*result = OBJECT_TO_JSVAL(obj);
result.setObject(*obj);
break;
}
case TYPE_function:
@ -2627,7 +2627,7 @@ ImplicitConvert(JSContext* cx,
RootedId id(cx);
size_t i = 0;
while (1) {
if (!JS_NextProperty(cx, iter, id.address()))
if (!JS_NextProperty(cx, iter, &id))
return false;
if (JSID_IS_VOID(id))
break;
@ -4194,7 +4194,7 @@ PointerType::ContentsGetter(JSContext* cx, JS::CallArgs args)
}
RootedValue result(cx);
if (!ConvertToJS(cx, baseType, NullPtr(), data, false, false, result.address()))
if (!ConvertToJS(cx, baseType, NullPtr(), data, false, false, &result))
return false;
args.rval().set(result);
@ -4290,8 +4290,8 @@ ArrayType::CreateInternal(JSContext* cx,
JS_ReportError(cx, "size overflow");
return nullptr;
}
if (!SizeTojsval(cx, size, sizeVal.address()) ||
!SizeTojsval(cx, length, lengthVal.address()))
if (!SizeTojsval(cx, size, &sizeVal) ||
!SizeTojsval(cx, length, &lengthVal))
return nullptr;
}
@ -4589,7 +4589,7 @@ ArrayType::Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle
RootedObject baseType(cx, GetBaseType(typeObj));
size_t elementSize = CType::GetSize(baseType);
char* data = static_cast<char*>(CData::GetData(obj)) + elementSize * index;
return ConvertToJS(cx, baseType, obj, data, false, false, vp.address());
return ConvertToJS(cx, baseType, obj, data, false, false, vp);
}
bool
@ -4686,7 +4686,7 @@ ArrayType::AddressOfElement(JSContext* cx, unsigned argc, jsval* vp)
// For a struct field descriptor 'val' of the form { name : type }, extract
// 'name' and 'type'.
static JSFlatString*
ExtractStructField(JSContext* cx, jsval val, JSObject** typeObj)
ExtractStructField(JSContext* cx, jsval val, MutableHandleObject typeObj)
{
if (val.isPrimitive()) {
JS_ReportError(cx, "struct field descriptors require a valid name and type");
@ -4699,7 +4699,7 @@ ExtractStructField(JSContext* cx, jsval val, JSObject** typeObj)
return nullptr;
RootedId nameid(cx);
if (!JS_NextProperty(cx, iter, nameid.address()))
if (!JS_NextProperty(cx, iter, &nameid))
return nullptr;
if (JSID_IS_VOID(nameid)) {
JS_ReportError(cx, "struct field descriptors require a valid name and type");
@ -4712,7 +4712,7 @@ ExtractStructField(JSContext* cx, jsval val, JSObject** typeObj)
}
// make sure we have one, and only one, property
jsid id;
RootedId id(cx);
if (!JS_NextProperty(cx, iter, &id))
return nullptr;
if (!JSID_IS_VOID(id)) {
@ -4732,9 +4732,9 @@ ExtractStructField(JSContext* cx, jsval val, JSObject** typeObj)
// Undefined size or zero size struct members are illegal.
// (Zero-size arrays are legal as struct members in C++, but libffi will
// choke on a zero-size struct, so we disallow them.)
*typeObj = &propVal.toObject();
typeObj.set(&propVal.toObject());
size_t size;
if (!CType::GetSafeSize(*typeObj, &size) || size == 0) {
if (!CType::GetSafeSize(typeObj, &size) || size == 0) {
JS_ReportError(cx, "struct field types must have defined and nonzero size");
return nullptr;
}
@ -4746,7 +4746,7 @@ ExtractStructField(JSContext* cx, jsval val, JSObject** typeObj)
// { name : type }.
static bool
AddFieldToArray(JSContext* cx,
jsval* element,
MutableHandleValue element,
JSFlatString* name_,
JSObject* typeObj_)
{
@ -4756,7 +4756,7 @@ AddFieldToArray(JSContext* cx,
if (!fieldObj)
return false;
*element = OBJECT_TO_JSVAL(fieldObj);
element.setObject(*fieldObj);
AutoStableStringChars nameChars(cx);
if (!nameChars.initTwoByte(cx, name))
@ -4882,7 +4882,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
return false;
RootedObject fieldType(cx, nullptr);
Rooted<JSFlatString*> name(cx, ExtractStructField(cx, item, fieldType.address()));
Rooted<JSFlatString*> name(cx, ExtractStructField(cx, item, &fieldType));
if (!name)
return false;
fieldRoots[i].setObject(*fieldType);
@ -4948,7 +4948,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
}
RootedValue sizeVal(cx);
if (!SizeTojsval(cx, structSize, sizeVal.address()))
if (!SizeTojsval(cx, structSize, &sizeVal))
return false;
JS_SetReservedSlot(typeObj, SLOT_FIELDINFO, PRIVATE_TO_JSVAL(fields.forget()));
@ -5197,7 +5197,7 @@ StructType::BuildFieldsArray(JSContext* cx, JSObject* obj)
for (FieldInfoHash::Range r = fields->all(); !r.empty(); r.popFront()) {
const FieldInfoHash::Entry& entry = r.front();
// Add the field descriptor to the array.
if (!AddFieldToArray(cx, fieldsVec[entry.value().mIndex].address(),
if (!AddFieldToArray(cx, fieldsVec[entry.value().mIndex],
entry.key(), entry.value().mType))
return nullptr;
}
@ -5269,7 +5269,7 @@ StructType::FieldGetter(JSContext* cx, HandleObject obj, HandleId idval, Mutable
char* data = static_cast<char*>(CData::GetData(obj)) + field->mOffset;
RootedObject fieldType(cx, field->mType);
return ConvertToJS(cx, fieldType, obj, data, false, false, vp.address());
return ConvertToJS(cx, fieldType, obj, data, false, false, vp);
}
bool
@ -5962,7 +5962,7 @@ FunctionType::Call(JSContext* cx,
// prepare a JS object from the result
RootedObject returnType(cx, fninfo->mReturnType);
return ConvertToJS(cx, returnType, NullPtr(), returnValue.mData, false, true, vp);
return ConvertToJS(cx, returnType, NullPtr(), returnValue.mData, false, true, args.rval());
}
FunctionInfo*
@ -6242,7 +6242,7 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData)
// Convert each argument, and have any CData objects created depend on
// the existing buffers.
RootedObject argType(cx, fninfo->mArgTypes[i]);
if (!ConvertToJS(cx, argType, NullPtr(), args[i], false, false, argv[i].address()))
if (!ConvertToJS(cx, argType, NullPtr(), args[i], false, false, argv[i]))
return;
}
@ -6478,7 +6478,7 @@ CData::ValueGetter(JSContext* cx, JS::CallArgs args)
// Convert the value to a primitive; do not create a new CData object.
RootedObject ctype(cx, GetCType(obj));
return ConvertToJS(cx, ctype, NullPtr(), GetData(obj), true, false, args.rval().address());
return ConvertToJS(cx, ctype, NullPtr(), GetData(obj), true, false, args.rval());
}
bool
@ -6844,7 +6844,7 @@ CDataFinalizer::Methods::ToString(JSContext *cx, unsigned argc, jsval *vp)
if (!strMessage) {
return false;
}
} else if (!CDataFinalizer::GetValue(cx, objThis, value.address())) {
} else if (!CDataFinalizer::GetValue(cx, objThis, &value)) {
MOZ_CRASH("Could not convert an empty CDataFinalizer");
} else {
strMessage = ToString(cx, value);
@ -6892,7 +6892,7 @@ CDataFinalizer::GetCData(JSContext *cx, JSObject *obj)
return nullptr;
}
RootedValue val(cx);
if (!CDataFinalizer::GetValue(cx, obj, val.address()) || val.isPrimitive()) {
if (!CDataFinalizer::GetValue(cx, obj, &val) || val.isPrimitive()) {
JS_ReportError(cx, "Empty CDataFinalizer");
return nullptr;
}
@ -6900,7 +6900,7 @@ CDataFinalizer::GetCData(JSContext *cx, JSObject *obj)
}
bool
CDataFinalizer::GetValue(JSContext *cx, JSObject *obj, jsval *aResult)
CDataFinalizer::GetValue(JSContext *cx, JSObject *obj, MutableHandleValue aResult)
{
MOZ_ASSERT(IsCDataFinalizer(obj));
@ -7184,7 +7184,7 @@ CDataFinalizer::Methods::Forget(JSContext* cx, unsigned argc, jsval *vp)
RootedValue valJSData(cx);
RootedObject ctype(cx, GetCType(cx, obj));
if (!ConvertToJS(cx, ctype, NullPtr(), p->cargs, false, true, valJSData.address())) {
if (!ConvertToJS(cx, ctype, NullPtr(), p->cargs, false, true, &valJSData)) {
JS_ReportError(cx, "CDataFinalizer value cannot be represented");
return false;
}
@ -7261,7 +7261,7 @@ CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, jsval *vp)
JS_SetReservedSlot(objCTypes, SLOT_LASTERROR, INT_TO_JSVAL(lastErrorStatus));
#endif // defined(XP_WIN)
if (ConvertToJS(cx, resultType, NullPtr(), p->rvalue, false, true, result.address())) {
if (ConvertToJS(cx, resultType, NullPtr(), p->rvalue, false, true, &result)) {
CDataFinalizer::Cleanup(p, obj);
args.rval().set(result);
return true;

View File

@ -546,6 +546,9 @@ class GCRuntime
void checkForCompartmentMismatches();
#endif
void callFinalizeCallbacks(FreeOp *fop, JSFinalizeStatus status) const;
void callMovingGCCallbacks() const;
public:
JSRuntime *rt;

View File

@ -9838,7 +9838,7 @@ DoIteratorMoreFallback(JSContext *cx, BaselineFrame *frame, ICIteratorMore_Fallb
FallbackICSpew(cx, stub, "IteratorMore");
bool cond;
if (!js_IteratorMore(cx, iterObj, &cond))
if (!IteratorMore(cx, iterObj, &cond))
return false;
res.setBoolean(cond);

View File

@ -6370,7 +6370,7 @@ LoadNativeIterator(MacroAssembler &masm, Register obj, Register dest, Label *fai
}
typedef bool (*IteratorNextFn)(JSContext *, HandleObject, MutableHandleValue);
static const VMFunction IteratorNextInfo = FunctionInfo<IteratorNextFn>(js_IteratorNext);
static const VMFunction IteratorNextInfo = FunctionInfo<IteratorNextFn>(IteratorNext);
bool
CodeGenerator::visitIteratorNext(LIteratorNext *lir)
@ -6401,7 +6401,7 @@ CodeGenerator::visitIteratorNext(LIteratorNext *lir)
}
typedef bool (*IteratorMoreFn)(JSContext *, HandleObject, bool *);
static const VMFunction IteratorMoreInfo = FunctionInfo<IteratorMoreFn>(js_IteratorMore);
static const VMFunction IteratorMoreInfo = FunctionInfo<IteratorMoreFn>(IteratorMore);
bool
CodeGenerator::visitIteratorMore(LIteratorMore *lir)

View File

@ -3218,26 +3218,43 @@ JS_DefineObject(JSContext *cx, HandleObject obj, const char *name, const JSClass
return nobj;
}
JS_PUBLIC_API(bool)
JS_DefineConstDoubles(JSContext *cx, HandleObject obj, const JSConstDoubleSpec *cds)
static inline Value
ValueFromScalar(double x)
{
bool ok;
unsigned attrs;
return DoubleValue(x);
}
static inline Value
ValueFromScalar(int32_t x)
{
return Int32Value(x);
}
template<typename T>
static bool
DefineConstScalar(JSContext *cx, HandleObject obj, const JSConstScalarSpec<T> *cds)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
JSPropertyOpWrapper noget = GetterWrapper(nullptr);
JSStrictPropertyOpWrapper noset = SetterWrapper(nullptr);
for (ok = true; cds->name; cds++) {
RootedValue value(cx, DoubleValue(cds->dval));
attrs = cds->flags;
if (!attrs)
attrs = JSPROP_READONLY | JSPROP_PERMANENT;
ok = DefineProperty(cx, obj, cds->name, value, noget, noset, attrs, 0);
if (!ok)
break;
unsigned attrs = JSPROP_READONLY | JSPROP_PERMANENT;
for (; cds->name; cds++) {
RootedValue value(cx, ValueFromScalar(cds->val));
if (!DefineProperty(cx, obj, cds->name, value, noget, noset, attrs, 0))
return false;
}
return ok;
return true;
}
JS_PUBLIC_API(bool)
JS_DefineConstDoubles(JSContext *cx, HandleObject obj, const JSConstDoubleSpec *cds)
{
return DefineConstScalar(cx, obj, cds);
}
JS_PUBLIC_API(bool)
JS_DefineConstIntegers(JSContext *cx, HandleObject obj, const JSConstIntegerSpec *cis)
{
return DefineConstScalar(cx, obj, cis);
}
JS_PUBLIC_API(bool)
@ -3707,7 +3724,7 @@ JS_NewPropertyIterator(JSContext *cx, HandleObject obj)
}
JS_PUBLIC_API(bool)
JS_NextProperty(JSContext *cx, HandleObject iterobj, jsid *idp)
JS_NextProperty(JSContext *cx, HandleObject iterobj, MutableHandleId idp)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -3723,10 +3740,10 @@ JS_NextProperty(JSContext *cx, HandleObject iterobj, jsid *idp)
if (!shape->previous()) {
JS_ASSERT(shape->isEmptyShape());
*idp = JSID_VOID;
idp.set(JSID_VOID);
} else {
iterobj->setPrivateGCThing(const_cast<Shape *>(shape->previous().get()));
*idp = shape->propid();
idp.set(shape->propid());
}
} else {
/* Non-native case: use the ida enumerated when iterobj was created. */
@ -3734,9 +3751,9 @@ JS_NextProperty(JSContext *cx, HandleObject iterobj, jsid *idp)
JS_ASSERT(i <= ida->length);
STATIC_ASSUME(i <= ida->length);
if (i == 0) {
*idp = JSID_VOID;
idp.set(JSID_VOID);
} else {
*idp = ida->vector[--i];
idp.set(ida->vector[--i]);
iterobj->setSlot(JSSLOT_ITER_INDEX, Int32Value(i));
}
}
@ -6143,7 +6160,7 @@ JS_PUBLIC_API(bool)
JS_ThrowStopIteration(JSContext *cx)
{
AssertHeapIsIdle(cx);
return js_ThrowStopIteration(cx);
return ThrowStopIteration(cx);
}
JS_PUBLIC_API(bool)

View File

@ -2303,13 +2303,15 @@ extern JS_PUBLIC_API(bool)
JS_ConvertStub(JSContext *cx, JS::HandleObject obj, JSType type,
JS::MutableHandleValue vp);
struct JSConstDoubleSpec {
double dval;
const char *name;
uint8_t flags;
uint8_t spare[3];
template<typename T>
struct JSConstScalarSpec {
const char *name;
T val;
};
typedef JSConstScalarSpec<double> JSConstDoubleSpec;
typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
struct JSJitInfo;
/*
@ -2766,6 +2768,9 @@ JS_DefineObject(JSContext *cx, JS::HandleObject obj, const char *name,
extern JS_PUBLIC_API(bool)
JS_DefineConstDoubles(JSContext *cx, JS::HandleObject obj, const JSConstDoubleSpec *cds);
extern JS_PUBLIC_API(bool)
JS_DefineConstIntegers(JSContext *cx, JS::HandleObject obj, const JSConstIntegerSpec *cis);
extern JS_PUBLIC_API(bool)
JS_DefineProperties(JSContext *cx, JS::HandleObject obj, const JSPropertySpec *ps);
@ -3286,7 +3291,7 @@ JS_NewPropertyIterator(JSContext *cx, JS::Handle<JSObject*> obj);
* left to visit. Return false on error.
*/
extern JS_PUBLIC_API(bool)
JS_NextProperty(JSContext *cx, JS::Handle<JSObject*> iterobj, jsid *idp);
JS_NextProperty(JSContext *cx, JS::HandleObject iterobj, JS::MutableHandleId idp);
extern JS_PUBLIC_API(jsval)
JS_GetReservedSlot(JSObject *obj, uint32_t index);

View File

@ -346,7 +346,7 @@ DeleteArrayElement(JSContext *cx, HandleObject obj, double index, bool *succeede
obj->markDenseElementsNotPacked(cx);
obj->setDenseElement(idx, MagicValue(JS_ELEMENTS_HOLE));
}
if (!js_SuppressDeletedElement(cx, obj, idx))
if (!SuppressDeletedElement(cx, obj, idx))
return false;
}
}
@ -1377,12 +1377,14 @@ array_reverse(JSContext *cx, unsigned argc, Value *vp)
orighi = obj->getDenseElement(hi);
obj->setDenseElement(lo, orighi);
if (orighi.isMagic(JS_ELEMENTS_HOLE) &&
!js_SuppressDeletedProperty(cx, obj, INT_TO_JSID(lo))) {
!SuppressDeletedProperty(cx, obj, INT_TO_JSID(lo)))
{
return false;
}
obj->setDenseElement(hi, origlo);
if (origlo.isMagic(JS_ELEMENTS_HOLE) &&
!js_SuppressDeletedProperty(cx, obj, INT_TO_JSID(hi))) {
!SuppressDeletedProperty(cx, obj, INT_TO_JSID(hi)))
{
return false;
}
}
@ -2211,7 +2213,7 @@ js::array_shift(JSContext *cx, unsigned argc, Value *vp)
if (!SetLengthProperty(cx, obj, newlen))
return false;
return js_SuppressDeletedProperty(cx, obj, INT_TO_JSID(newlen));
return SuppressDeletedProperty(cx, obj, INT_TO_JSID(newlen));
}
/* Steps 5, 10. */

View File

@ -1204,14 +1204,19 @@ date_now(JSContext *cx, unsigned argc, Value *vp)
}
void
DateObject::setUTCTime(double t, Value *vp)
DateObject::setUTCTime(double t)
{
for (size_t ind = COMPONENTS_START_SLOT; ind < RESERVED_SLOTS; ind++)
setReservedSlot(ind, UndefinedValue());
setFixedSlot(UTC_TIME_SLOT, DoubleValue(t));
if (vp)
vp->setDouble(t);
}
void
DateObject::setUTCTime(double t, MutableHandleValue vp)
{
setUTCTime(t);
vp.setDouble(t);
}
void
@ -1674,7 +1679,7 @@ date_setTime_impl(JSContext *cx, CallArgs args)
{
Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
if (args.length() == 0) {
dateObj->setUTCTime(GenericNaN(), args.rval().address());
dateObj->setUTCTime(GenericNaN(), args.rval());
return true;
}
@ -1682,7 +1687,7 @@ date_setTime_impl(JSContext *cx, CallArgs args)
if (!ToNumber(cx, args[0], &result))
return false;
dateObj->setUTCTime(TimeClip(result), args.rval().address());
dateObj->setUTCTime(TimeClip(result), args.rval());
return true;
}
@ -1742,7 +1747,7 @@ date_setMilliseconds_impl(JSContext *cx, CallArgs args)
double u = TimeClip(UTC(MakeDate(Day(t), time), &cx->runtime()->dateTimeInfo));
/* Steps 4-5. */
dateObj->setUTCTime(u, args.rval().address());
dateObj->setUTCTime(u, args.rval());
return true;
}
@ -1772,7 +1777,7 @@ date_setUTCMilliseconds_impl(JSContext *cx, CallArgs args)
double v = TimeClip(MakeDate(Day(t), time));
/* Steps 4-5. */
dateObj->setUTCTime(v, args.rval().address());
dateObj->setUTCTime(v, args.rval());
return true;
}
@ -1809,7 +1814,7 @@ date_setSeconds_impl(JSContext *cx, CallArgs args)
double u = TimeClip(UTC(date, &cx->runtime()->dateTimeInfo));
/* Steps 6-7. */
dateObj->setUTCTime(u, args.rval().address());
dateObj->setUTCTime(u, args.rval());
return true;
}
@ -1846,7 +1851,7 @@ date_setUTCSeconds_impl(JSContext *cx, CallArgs args)
double v = TimeClip(date);
/* Steps 6-7. */
dateObj->setUTCTime(v, args.rval().address());
dateObj->setUTCTime(v, args.rval());
return true;
}
@ -1888,7 +1893,7 @@ date_setMinutes_impl(JSContext *cx, CallArgs args)
double u = TimeClip(UTC(date, &cx->runtime()->dateTimeInfo));
/* Steps 7-8. */
dateObj->setUTCTime(u, args.rval().address());
dateObj->setUTCTime(u, args.rval());
return true;
}
@ -1930,7 +1935,7 @@ date_setUTCMinutes_impl(JSContext *cx, CallArgs args)
double v = TimeClip(date);
/* Steps 7-8. */
dateObj->setUTCTime(v, args.rval().address());
dateObj->setUTCTime(v, args.rval());
return true;
}
@ -1977,7 +1982,7 @@ date_setHours_impl(JSContext *cx, CallArgs args)
double u = TimeClip(UTC(date, &cx->runtime()->dateTimeInfo));
/* Steps 7-8. */
dateObj->setUTCTime(u, args.rval().address());
dateObj->setUTCTime(u, args.rval());
return true;
}
@ -2024,7 +2029,7 @@ date_setUTCHours_impl(JSContext *cx, CallArgs args)
double v = TimeClip(newDate);
/* Steps 8-9. */
dateObj->setUTCTime(v, args.rval().address());
dateObj->setUTCTime(v, args.rval());
return true;
}
@ -2056,7 +2061,7 @@ date_setDate_impl(JSContext *cx, CallArgs args)
double u = TimeClip(UTC(newDate, &cx->runtime()->dateTimeInfo));
/* Steps 5-6. */
dateObj->setUTCTime(u, args.rval().address());
dateObj->setUTCTime(u, args.rval());
return true;
}
@ -2088,7 +2093,7 @@ date_setUTCDate_impl(JSContext *cx, CallArgs args)
double v = TimeClip(newDate);
/* Steps 5-6. */
dateObj->setUTCTime(v, args.rval().address());
dateObj->setUTCTime(v, args.rval());
return true;
}
@ -2145,7 +2150,7 @@ date_setMonth_impl(JSContext *cx, CallArgs args)
double u = TimeClip(UTC(newDate, &cx->runtime()->dateTimeInfo));
/* Steps 6-7. */
dateObj->setUTCTime(u, args.rval().address());
dateObj->setUTCTime(u, args.rval());
return true;
}
@ -2182,7 +2187,7 @@ date_setUTCMonth_impl(JSContext *cx, CallArgs args)
double v = TimeClip(newDate);
/* Steps 6-7. */
dateObj->setUTCTime(v, args.rval().address());
dateObj->setUTCTime(v, args.rval());
return true;
}
@ -2240,7 +2245,7 @@ date_setFullYear_impl(JSContext *cx, CallArgs args)
double u = TimeClip(UTC(newDate, &cx->runtime()->dateTimeInfo));
/* Steps 7-8. */
dateObj->setUTCTime(u, args.rval().address());
dateObj->setUTCTime(u, args.rval());
return true;
}
@ -2282,7 +2287,7 @@ date_setUTCFullYear_impl(JSContext *cx, CallArgs args)
double v = TimeClip(newDate);
/* Steps 7-8. */
dateObj->setUTCTime(v, args.rval().address());
dateObj->setUTCTime(v, args.rval());
return true;
}
@ -2309,7 +2314,7 @@ date_setYear_impl(JSContext *cx, CallArgs args)
/* Step 3. */
if (IsNaN(y)) {
dateObj->setUTCTime(GenericNaN(), args.rval().address());
dateObj->setUTCTime(GenericNaN(), args.rval());
return true;
}
@ -2325,7 +2330,7 @@ date_setYear_impl(JSContext *cx, CallArgs args)
double u = UTC(MakeDate(day, TimeWithinDay(t)), &cx->runtime()->dateTimeInfo);
/* Steps 7-8. */
dateObj->setUTCTime(TimeClip(u), args.rval().address());
dateObj->setUTCTime(TimeClip(u), args.rval());
return true;
}

View File

@ -395,6 +395,14 @@ js::GetGlobalForObjectCrossCompartment(JSObject *obj)
return &obj->global();
}
JS_FRIEND_API(JSObject *)
js::GetPrototypeNoProxy(JSObject *obj)
{
JS_ASSERT(!obj->is<js::ProxyObject>());
JS_ASSERT(!obj->getTaggedProto().isLazy());
return obj->getTaggedProto().toObjectOrNull();
}
JS_FRIEND_API(void)
js::SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v)
{

View File

@ -706,6 +706,9 @@ GetObjectParentMaybeScope(JSObject *obj);
JS_FRIEND_API(JSObject *)
GetGlobalForObjectCrossCompartment(JSObject *obj);
JS_FRIEND_API(JSObject *)
GetPrototypeNoProxy(JSObject *obj);
// Sidestep the activeContext checking implicitly performed in
// JS_SetPendingException.
JS_FRIEND_API(void)

View File

@ -1588,7 +1588,8 @@ void
GCRuntime::removeFinalizeCallback(JSFinalizeCallback callback)
{
for (Callback<JSFinalizeCallback> *p = finalizeCallbacks.begin();
p < finalizeCallbacks.end(); p++) {
p < finalizeCallbacks.end(); p++)
{
if (p->op == callback) {
finalizeCallbacks.erase(p);
break;
@ -1596,6 +1597,16 @@ GCRuntime::removeFinalizeCallback(JSFinalizeCallback callback)
}
}
void
GCRuntime::callFinalizeCallbacks(FreeOp *fop, JSFinalizeStatus status) const
{
for (const Callback<JSFinalizeCallback> *p = finalizeCallbacks.begin();
p < finalizeCallbacks.end(); p++)
{
p->op(fop, status, !isFull, p->data);
}
}
bool
GCRuntime::addMovingGCCallback(JSMovingGCCallback callback, void *data)
{
@ -1615,6 +1626,16 @@ GCRuntime::removeMovingGCCallback(JSMovingGCCallback callback)
}
}
void
GCRuntime::callMovingGCCallbacks() const
{
for (const Callback<JSMovingGCCallback> *p = movingCallbacks.begin();
p < movingCallbacks.end(); p++)
{
p->op(rt, p->data);
}
}
JS::GCSliceCallback
GCRuntime::setSliceCallback(JS::GCSliceCallback callback) {
return stats.setSliceCallback(callback);
@ -2438,11 +2459,7 @@ GCRuntime::updatePointersToRelocatedCells()
MovingTracer::Sweep(&trc);
// Call callbacks to get the rest of the system to fixup other untraced pointers.
for (Callback<JSMovingGCCallback> *p = rt->gc.movingCallbacks.begin();
p < rt->gc.movingCallbacks.end(); p++)
{
p->op(rt, p->data);
}
callMovingGCCallbacks();
}
void
@ -4623,11 +4640,7 @@ GCRuntime::beginSweepingZoneGroup()
{
gcstats::AutoPhase ap(stats, gcstats::PHASE_FINALIZE_START);
for (Callback<JSFinalizeCallback> *p = rt->gc.finalizeCallbacks.begin();
p < rt->gc.finalizeCallbacks.end(); p++)
{
p->op(&fop, JSFINALIZE_GROUP_START, !isFull /* unused */, p->data);
}
callFinalizeCallbacks(&fop, JSFINALIZE_GROUP_START);
}
if (sweepingAtoms) {
@ -4724,11 +4737,7 @@ GCRuntime::beginSweepingZoneGroup()
{
gcstats::AutoPhase ap(stats, gcstats::PHASE_FINALIZE_END);
for (Callback<JSFinalizeCallback> *p = rt->gc.finalizeCallbacks.begin();
p < rt->gc.finalizeCallbacks.end(); p++)
{
p->op(&fop, JSFINALIZE_GROUP_END, !isFull /* unused */, p->data);
}
callFinalizeCallbacks(&fop, JSFINALIZE_GROUP_END);
}
}
@ -4962,12 +4971,7 @@ GCRuntime::endSweepPhase(bool lastGC)
{
gcstats::AutoPhase ap(stats, gcstats::PHASE_FINALIZE_END);
for (Callback<JSFinalizeCallback> *p = rt->gc.finalizeCallbacks.begin();
p < rt->gc.finalizeCallbacks.end(); p++)
{
p->op(&fop, JSFINALIZE_COLLECTION_END, !isFull, p->data);
}
callFinalizeCallbacks(&fop, JSFINALIZE_COLLECTION_END);
/* If we finished a full GC, then the gray bits are correct. */
if (isFull)

View File

@ -817,7 +817,7 @@ js::CreateItrResultObject(JSContext *cx, HandleValue value, bool done)
}
bool
js_ThrowStopIteration(JSContext *cx)
js::ThrowStopIteration(JSContext *cx)
{
JS_ASSERT(!JS_IsExceptionPending(cx));
@ -865,15 +865,15 @@ iterator_next_impl(JSContext *cx, CallArgs args)
RootedObject thisObj(cx, &args.thisv().toObject());
bool more;
if (!js_IteratorMore(cx, thisObj, &more))
if (!IteratorMore(cx, thisObj, &more))
return false;
if (!more) {
js_ThrowStopIteration(cx);
ThrowStopIteration(cx);
return false;
}
return js_IteratorNext(cx, thisObj, args.rval());
return IteratorNext(cx, thisObj, args.rval());
}
static bool
@ -1209,7 +1209,7 @@ public:
} /* anonymous namespace */
bool
js_SuppressDeletedProperty(JSContext *cx, HandleObject obj, jsid id)
js::SuppressDeletedProperty(JSContext *cx, HandleObject obj, jsid id)
{
if (JSID_IS_SYMBOL(id))
return true;
@ -1221,12 +1221,12 @@ js_SuppressDeletedProperty(JSContext *cx, HandleObject obj, jsid id)
}
bool
js_SuppressDeletedElement(JSContext *cx, HandleObject obj, uint32_t index)
js::SuppressDeletedElement(JSContext *cx, HandleObject obj, uint32_t index)
{
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return js_SuppressDeletedProperty(cx, obj, id);
return SuppressDeletedProperty(cx, obj, id);
}
namespace {
@ -1248,13 +1248,13 @@ class IndexRangePredicate {
} /* anonymous namespace */
bool
js_SuppressDeletedElements(JSContext *cx, HandleObject obj, uint32_t begin, uint32_t end)
js::SuppressDeletedElements(JSContext *cx, HandleObject obj, uint32_t begin, uint32_t end)
{
return SuppressDeletedPropertyHelper(cx, obj, IndexRangePredicate(begin, end));
}
bool
js_IteratorMore(JSContext *cx, HandleObject iterobj, bool *res)
js::IteratorMore(JSContext *cx, HandleObject iterobj, bool *res)
{
/* Fast path for native iterators */
NativeIterator *ni = nullptr;
@ -1320,7 +1320,7 @@ js_IteratorMore(JSContext *cx, HandleObject iterobj, bool *res)
}
bool
js_IteratorNext(JSContext *cx, HandleObject iterobj, MutableHandleValue rval)
js::IteratorNext(JSContext *cx, HandleObject iterobj, MutableHandleValue rval)
{
/* Fast path for native iterators */
if (iterobj->is<PropertyIteratorObject>()) {
@ -1888,7 +1888,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj,
// if needed.
rval.setUndefined();
if (op != JSGENOP_CLOSE)
ok = js_ThrowStopIteration(cx);
ok = ThrowStopIteration(cx);
}
}
@ -1936,7 +1936,7 @@ legacy_generator_next(JSContext *cx, CallArgs args)
JSGenerator *gen = thisObj->as<LegacyGeneratorObject>().getGenerator();
if (gen->state == JSGEN_CLOSED)
return js_ThrowStopIteration(cx);
return ThrowStopIteration(cx);
return SendToGenerator(cx, JSGENOP_SEND, thisObj, gen, args.get(0), LegacyGenerator,
args.rval());

View File

@ -183,7 +183,7 @@ bool
CloseIterator(JSContext *cx, HandleObject iterObj);
bool
UnwindIteratorForException(JSContext *cx, js::HandleObject obj);
UnwindIteratorForException(JSContext *cx, HandleObject obj);
void
UnwindIteratorForUncatchableException(JSContext *cx, JSObject *obj);
@ -191,16 +191,14 @@ UnwindIteratorForUncatchableException(JSContext *cx, JSObject *obj);
bool
IteratorConstructor(JSContext *cx, unsigned argc, Value *vp);
} /* namespace js */
extern bool
SuppressDeletedProperty(JSContext *cx, HandleObject obj, jsid id);
extern bool
js_SuppressDeletedProperty(JSContext *cx, js::HandleObject obj, jsid id);
SuppressDeletedElement(JSContext *cx, HandleObject obj, uint32_t index);
extern bool
js_SuppressDeletedElement(JSContext *cx, js::HandleObject obj, uint32_t index);
extern bool
js_SuppressDeletedElements(JSContext *cx, js::HandleObject obj, uint32_t begin, uint32_t end);
SuppressDeletedElements(JSContext *cx, HandleObject obj, uint32_t begin, uint32_t end);
/*
* IteratorMore() indicates whether another value is available. It might
@ -208,22 +206,20 @@ js_SuppressDeletedElements(JSContext *cx, js::HandleObject obj, uint32_t begin,
* picked up by IteratorNext(). The value is cached in the current context.
*/
extern bool
js_IteratorMore(JSContext *cx, js::HandleObject iterobj, bool *res);
IteratorMore(JSContext *cx, HandleObject iterobj, bool *res);
extern bool
js_IteratorNext(JSContext *cx, js::HandleObject iterobj, js::MutableHandleValue rval);
IteratorNext(JSContext *cx, HandleObject iterobj, MutableHandleValue rval);
extern bool
js_ThrowStopIteration(JSContext *cx);
namespace js {
ThrowStopIteration(JSContext *cx);
/*
* Create an object of the form { value: VALUE, done: DONE }.
* ES6 draft from 2013-09-05, section 25.4.3.4.
*/
extern JSObject *
CreateItrResultObject(JSContext *cx, js::HandleValue value, bool done);
CreateItrResultObject(JSContext *cx, HandleValue value, bool done);
} /* namespace js */

View File

@ -50,15 +50,15 @@ using JS::ToNumber;
using JS::GenericNaN;
static const JSConstDoubleSpec math_constants[] = {
{M_E, "E", 0, {0,0,0}},
{M_LOG2E, "LOG2E", 0, {0,0,0}},
{M_LOG10E, "LOG10E", 0, {0,0,0}},
{M_LN2, "LN2", 0, {0,0,0}},
{M_LN10, "LN10", 0, {0,0,0}},
{M_PI, "PI", 0, {0,0,0}},
{M_SQRT2, "SQRT2", 0, {0,0,0}},
{M_SQRT1_2, "SQRT1_2", 0, {0,0,0}},
{0,0,0,{0,0,0}}
{"E" , M_E },
{"LOG2E" , M_LOG2E },
{"LOG10E" , M_LOG10E },
{"LN2" , M_LN2 },
{"LN10" , M_LN10 },
{"PI" , M_PI },
{"SQRT2" , M_SQRT2 },
{"SQRT1_2", M_SQRT1_2 },
{0,0}
};
MathCache::MathCache() {

View File

@ -1061,18 +1061,18 @@ enum nc_slot {
* using union jsdpun.
*/
static JSConstDoubleSpec number_constants[] = {
{0, "NaN", 0,{0,0,0}},
{0, "POSITIVE_INFINITY", 0,{0,0,0}},
{0, "NEGATIVE_INFINITY", 0,{0,0,0}},
{1.7976931348623157E+308, "MAX_VALUE", 0,{0,0,0}},
{0, "MIN_VALUE", 0,{0,0,0}},
{"NaN", 0 },
{"POSITIVE_INFINITY", 0 },
{"NEGATIVE_INFINITY", 0 },
{"MAX_VALUE", 1.7976931348623157E+308 },
{"MIN_VALUE", 0 },
/* ES6 (April 2014 draft) 20.1.2.6 */
{9007199254740991, "MAX_SAFE_INTEGER", 0,{0,0,0}},
{"MAX_SAFE_INTEGER", 9007199254740991 },
/* ES6 (April 2014 draft) 20.1.2.10 */
{-9007199254740991, "MIN_SAFE_INTEGER", 0,{0,0,0}},
{"MIN_SAFE_INTEGER", -9007199254740991, },
/* ES6 (May 2013 draft) 15.7.3.7 */
{2.2204460492503130808472633361816e-16, "EPSILON", 0,{0,0,0}},
{0,0,0,{0,0,0}}
{"EPSILON", 2.2204460492503130808472633361816e-16},
{0,0}
};
/*
@ -1101,12 +1101,12 @@ js::InitRuntimeNumberState(JSRuntime *rt)
* Our NaN must be one particular canonical value, because we rely on NaN
* encoding for our value representation. See Value.h.
*/
number_constants[NC_NaN].dval = GenericNaN();
number_constants[NC_NaN].val = GenericNaN();
number_constants[NC_POSITIVE_INFINITY].dval = mozilla::PositiveInfinity<double>();
number_constants[NC_NEGATIVE_INFINITY].dval = mozilla::NegativeInfinity<double>();
number_constants[NC_POSITIVE_INFINITY].val = mozilla::PositiveInfinity<double>();
number_constants[NC_NEGATIVE_INFINITY].val = mozilla::NegativeInfinity<double>();
number_constants[NC_MIN_VALUE].dval = MinNumberValue<double>();
number_constants[NC_MIN_VALUE].val = MinNumberValue<double>();
// XXX If EXPOSE_INTL_API becomes true all the time at some point,
// js::InitRuntimeNumberState is no longer fallible, and we should

View File

@ -5749,7 +5749,7 @@ baseops::DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succe
return false;
obj->setDenseElementHole(cx, JSID_TO_INT(id));
return js_SuppressDeletedProperty(cx, obj, id);
return SuppressDeletedProperty(cx, obj, id);
}
if (!shape->configurable()) {
@ -5763,7 +5763,7 @@ baseops::DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succe
if (!succeeded)
return true;
return obj->removeProperty(cx, id) && js_SuppressDeletedProperty(cx, obj, id);
return obj->removeProperty(cx, id) && SuppressDeletedProperty(cx, obj, id);
}
bool

View File

@ -124,7 +124,6 @@ enum JSGCTraceKind {
/* Struct forward declarations. */
struct JSClass;
struct JSCompartment;
struct JSConstDoubleSpec;
struct JSCrossCompartmentCall;
struct JSErrorReport;
struct JSExceptionState;
@ -148,6 +147,10 @@ class JSFlatString;
typedef struct PRCallOnceType JSCallOnceType;
typedef bool (*JSInitCallback)(void);
template<typename T> struct JSConstScalarSpec;
typedef JSConstScalarSpec<double> JSConstDoubleSpec;
typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
/*
* Generic trace operation that calls JS_CallTracer on each traceable thing
* stored in data.

View File

@ -712,7 +712,7 @@ js::proxy_DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succ
if (!Proxy::delete_(cx, obj, id, &deleted))
return false;
*succeeded = deleted;
return js_SuppressDeletedProperty(cx, obj, id);
return SuppressDeletedProperty(cx, obj, id);
}
void

View File

@ -10,7 +10,6 @@
#define vm_CommonPropertyNames_h
#include "jsprototypes.h"
#include "builtin/SIMDShuffleMaskConstants.h"
#define FOR_EACH_COMMON_PROPERTYNAME(macro) \
macro(anonymous, anonymous, "anonymous") \
@ -232,6 +231,5 @@
macro(Symbol_toPrimitive, Symbol_toPrimitive, "Symbol.toPrimitive") \
macro(Symbol_toStringTag, Symbol_toStringTag, "Symbol.toStringTag") \
macro(Symbol_unscopables, Symbol_unscopables, "Symbol.unscopables") \
FOR_EACH_SIMD_SHUFFLE_MASK(COMMON_PROPERTY_NAMES_MACRO, macro)
#endif /* vm_CommonPropertyNames_h */

View File

@ -46,7 +46,8 @@ class DateObject : public JSObject
}
// Set UTC time to a given time and invalidate cached local time.
void setUTCTime(double t, Value *vp = nullptr);
void setUTCTime(double t);
void setUTCTime(double t, MutableHandleValue vp);
inline double cachedLocalTime(DateTimeInfo *dtInfo);

View File

@ -1116,21 +1116,6 @@ JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
JS_STATIC_ASSERT(JSOP_IFNE_LENGTH == JSOP_IFEQ_LENGTH);
JS_STATIC_ASSERT(JSOP_IFNE == JSOP_IFEQ + 1);
bool
js::IteratorNext(JSContext *cx, HandleObject iterobj, MutableHandleValue rval)
{
if (iterobj->is<PropertyIteratorObject>()) {
NativeIterator *ni = iterobj->as<PropertyIteratorObject>().getNativeIterator();
if (ni->isKeyIter()) {
JS_ASSERT(ni->props_cursor < ni->props_end);
rval.setString(*ni->current());
ni->incCursor();
return true;
}
}
return js_IteratorNext(cx, iterobj, rval);
}
/*
* Compute the implicit |this| parameter for a call expression where the callee
* funval was resolved from an unqualified name reference to a property on obj
@ -1909,7 +1894,7 @@ CASE(JSOP_MOREITER)
RootedObject &obj = rootObject0;
obj = &REGS.sp[-2].toObject();
bool cond;
if (!js_IteratorMore(cx, obj, &cond))
if (!IteratorMore(cx, obj, &cond))
goto error;
REGS.sp[-1].setBoolean(cond);
}

View File

@ -439,9 +439,6 @@ bool
ImplicitThisOperation(JSContext *cx, HandleObject scopeObj, HandlePropertyName name,
MutableHandleValue res);
bool
IteratorNext(JSContext *cx, HandleObject iterobj, MutableHandleValue rval);
bool
RunOnceScriptPrologue(JSContext *cx, HandleScript script);

View File

@ -637,22 +637,14 @@ xpc::SandboxProxyHandler::getPropertyDescriptor(JSContext *cx,
if (!desc.object())
return true; // No property, nothing to do
// Now fix up the getter/setter/value as needed to be bound to desc->obj
// Don't mess with holder_get and holder_set, though, because those rely on
// the "vp is prefilled with the value in the slot" behavior that property
// ops can in theory rely on, but our property op forwarder doesn't know how
// to make that happen. Since we really only need to rebind the DOM methods
// here, not rebindings holder_get and holder_set is OK.
// Now fix up the getter/setter/value as needed to be bound to desc->obj.
//
// Similarly, don't mess with XPC_WN_Helper_GetProperty and
// XPC_WN_Helper_SetProperty, for the same reasons: that could confuse our
// access to expandos when we're not doing Xrays.
if (desc.getter() != xpc::holder_get &&
desc.getter() != XPC_WN_Helper_GetProperty &&
// Don't mess with XPC_WN_Helper_GetProperty and XPC_WN_Helper_SetProperty,
// because that could confuse our access to expandos.
if (desc.getter() != XPC_WN_Helper_GetProperty &&
!BindPropertyOp(cx, desc.getter(), desc.address(), id, JSPROP_GETTER, proxy))
return false;
if (desc.setter() != xpc::holder_set &&
desc.setter() != XPC_WN_Helper_SetProperty &&
if (desc.setter() != XPC_WN_Helper_SetProperty &&
!BindPropertyOp(cx, desc.setter(), desc.address(), id, JSPROP_SETTER, proxy))
return false;
if (desc.value().isObject()) {

View File

@ -575,6 +575,25 @@ WindowGlobalOrNull(JSObject *aObj)
return WindowOrNull(glob);
}
nsGlobalWindow*
AddonWindowOrNull(JSObject *aObj)
{
if (!IsInAddonScope(aObj))
return nullptr;
JSObject *global = js::GetGlobalForObjectCrossCompartment(aObj);
JSObject *proto = js::GetPrototypeNoProxy(global);
// Addons could theoretically change the prototype of the addon scope, but
// we pretty much just want to crash if that happens so that we find out
// about it and get them to change their code.
MOZ_RELEASE_ASSERT(js::IsCrossCompartmentWrapper(proto));
JSObject *mainGlobal = js::UncheckedUnwrap(proto, /* stopAtOuter = */ false);
MOZ_RELEASE_ASSERT(JS_IsGlobalObject(mainGlobal));
return WindowOrNull(mainGlobal);
}
}
static void

View File

@ -70,8 +70,11 @@ nsXPCWrappedJS::CanSkip()
// For non-root wrappers, check if the root wrapper will be
// added to the CC graph.
if (!IsRootWrapper())
if (!IsRootWrapper()) {
// mRoot points to null after unlinking.
NS_ENSURE_TRUE(mRoot, false);
return mRoot->CanSkip();
}
// For the root wrapper, check if there is an aggregated
// native object that will be added to the CC graph.

View File

@ -472,6 +472,14 @@ WindowOrNull(JSObject *aObj);
nsGlobalWindow*
WindowGlobalOrNull(JSObject *aObj);
/**
* If |aObj| is in an addon scope and that addon scope is associated with a
* live DOM Window, returns the associated nsGlobalWindow. Otherwise, returns
* null.
*/
nsGlobalWindow*
AddonWindowOrNull(JSObject *aObj);
// Error reporter used when there is no associated DOM window on to which to
// report errors and warnings.
//

View File

@ -185,7 +185,7 @@ AccessCheck::isCrossOriginAccessPermitted(JSContext *cx, HandleObject wrapper, H
// Check for frame IDs. If we're resolving named frames, make sure to only
// resolve ones that don't shadow native properties. See bug 860494.
if (IsWindow(name)) {
if (JSID_IS_STRING(id) && !XrayUtils::IsXrayResolving(cx, wrapper, id)) {
if (JSID_IS_STRING(id)) {
bool wouldShadow = false;
if (!XrayUtils::HasNativeProperty(cx, wrapper, id, &wouldShadow) ||
wouldShadow)

View File

@ -156,22 +156,6 @@ bool
FilteringWrapper<Base, Policy>::enter(JSContext *cx, HandleObject wrapper,
HandleId id, Wrapper::Action act, bool *bp) const
{
// This is a super ugly hacky to get around Xray Resolve wonkiness.
//
// Basically, XPCWN Xrays sometimes call into the Resolve hook of the
// scriptable helper, and pass the wrapper itself as the object upon which
// the resolve is happening. Then, special handling happens in
// XrayWrapper::defineProperty to detect the resolve and redefine the
// property on the holder. Really, we should just pass the holder itself to
// NewResolve, but there's too much code in nsDOMClassInfo that assumes this
// isn't the case (in particular, code expects to be able to look up
// properties on the object, which doesn't work for the holder). Given that
// these hooks are going away eventually with the new DOM bindings, let's
// just hack around this for now.
if (XrayUtils::IsXrayResolving(cx, wrapper, id)) {
*bp = true;
return true;
}
if (!Policy::check(cx, wrapper, id, act)) {
*bp = JS_IsExceptionPending(cx) ? false : Policy::deny(act, id);
return false;
@ -240,11 +224,6 @@ CrossOriginXrayWrapper::defineProperty(JSContext *cx, JS::Handle<JSObject*> wrap
JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc) const
{
// Until XPCWN Xrays go away, we'll have native resolves looping back
// through here.
if (XrayUtils::IsXrayResolving(cx, wrapper, id))
return SecurityXrayDOM::defineProperty(cx, wrapper, id, desc);
JS_ReportError(cx, "Permission denied to define property on cross-origin object");
return false;
}

View File

@ -596,13 +596,6 @@ WrapperFactory::WaiveXrayAndWrap(JSContext *cx, MutableHandleObject argObj)
return true;
}
bool
WrapperFactory::XrayWrapperNotShadowing(JSObject *wrapper, jsid id)
{
ResolvingId *rid = ResolvingId::getResolvingIdFromWrapper(wrapper);
return rid->isXrayShadowing(id);
}
/*
* Calls to JS_TransplantObject* should go through these helpers here so that
* waivers get fixed up properly.

View File

@ -52,9 +52,6 @@ class WrapperFactory {
// Wrap wrapped object into a waiver wrapper and then re-wrap it.
static bool WaiveXrayAndWrap(JSContext *cx, JS::MutableHandleValue vp);
static bool WaiveXrayAndWrap(JSContext *cx, JS::MutableHandleObject object);
// Returns true if the wrapper is in not shadowing mode for the id.
static bool XrayWrapperNotShadowing(JSObject *wrapper, jsid id);
};
extern const js::Wrapper XrayWaiver;

View File

@ -126,62 +126,6 @@ XrayAwareCalleeGlobal(JSObject *fun)
return js::GetGlobalForObjectCrossCompartment(scope);
}
const uint32_t JSSLOT_RESOLVING = 0;
ResolvingId::ResolvingId(JSContext *cx, HandleObject wrapper, HandleId id)
: mId(id),
mHolder(cx, getHolderObject(wrapper)),
mPrev(getResolvingId(mHolder)),
mXrayShadowing(false)
{
js::SetReservedSlot(mHolder, JSSLOT_RESOLVING, js::PrivateValue(this));
}
ResolvingId::~ResolvingId()
{
MOZ_ASSERT(getResolvingId(mHolder) == this, "unbalanced ResolvingIds");
js::SetReservedSlot(mHolder, JSSLOT_RESOLVING, js::PrivateValue(mPrev));
}
bool
ResolvingId::isXrayShadowing(jsid id)
{
if (!mXrayShadowing)
return false;
return mId == id;
}
bool
ResolvingId::isResolving(jsid id)
{
for (ResolvingId *cur = this; cur; cur = cur->mPrev) {
if (cur->mId == id)
return true;
}
return false;
}
ResolvingId *
ResolvingId::getResolvingId(JSObject *holder)
{
MOZ_ASSERT(strcmp(JS_GetClass(holder)->name, "NativePropertyHolder") == 0);
return (ResolvingId *)js::GetReservedSlot(holder, JSSLOT_RESOLVING).toPrivate();
}
JSObject *
ResolvingId::getHolderObject(JSObject *wrapper)
{
return &js::GetProxyExtra(wrapper, 0).toObject();
}
ResolvingId *
ResolvingId::getResolvingIdFromWrapper(JSObject *wrapper)
{
return getResolvingId(getHolderObject(wrapper));
}
JSObject *
XrayTraits::getExpandoChain(HandleObject obj)
{
@ -203,8 +147,9 @@ XPCWrappedNativeXrayTraits::getWN(JSObject *wrapper)
const JSClass XPCWrappedNativeXrayTraits::HolderClass = {
"NativePropertyHolder", JSCLASS_HAS_RESERVED_SLOTS(2),
JS_PropertyStub, JS_DeletePropertyStub, holder_get, holder_set,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub,
JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub
};
@ -1087,16 +1032,6 @@ XrayTraits::ensureHolder(JSContext *cx, HandleObject wrapper)
return holder;
}
bool
XPCWrappedNativeXrayTraits::isResolving(JSContext *cx, JSObject *holder,
jsid id)
{
ResolvingId *cur = ResolvingId::getResolvingId(holder);
if (!cur)
return false;
return cur->isResolving(id);
}
namespace XrayUtils {
bool
@ -1107,135 +1042,6 @@ IsXPCWNHolderClass(const JSClass *clasp)
}
// Some DOM objects have shared properties that don't have an explicit
// getter/setter and rely on the class getter/setter. We install a
// class getter/setter on the holder object to trigger them.
bool
holder_get(JSContext *cx, HandleObject wrapper, HandleId id, MutableHandleValue vp)
{
// JSClass::getProperty is wacky enough that it's hard to be sure someone
// can't inherit this getter by prototyping a random object to an
// XrayWrapper. Be safe.
NS_ENSURE_TRUE(WrapperFactory::IsXrayWrapper(wrapper), true);
JSObject *holder = GetHolder(wrapper);
XPCWrappedNative *wn = XPCWrappedNativeXrayTraits::getWN(wrapper);
if (NATIVE_HAS_FLAG(wn, WantGetProperty)) {
JSAutoCompartment ac(cx, holder);
bool retval = true;
nsresult rv = wn->GetScriptableCallback()->GetProperty(wn, cx, wrapper,
id, vp.address(), &retval);
if (NS_FAILED(rv) || !retval) {
if (retval)
XPCThrower::Throw(rv, cx);
return false;
}
}
return true;
}
bool
holder_set(JSContext *cx, HandleObject wrapper, HandleId id, bool strict, MutableHandleValue vp)
{
// JSClass::setProperty is wacky enough that it's hard to be sure someone
// can't inherit this getter by prototyping a random object to an
// XrayWrapper. Be safe.
NS_ENSURE_TRUE(WrapperFactory::IsXrayWrapper(wrapper), true);
JSObject *holder = GetHolder(wrapper);
if (XPCWrappedNativeXrayTraits::isResolving(cx, holder, id)) {
return true;
}
XPCWrappedNative *wn = XPCWrappedNativeXrayTraits::getWN(wrapper);
if (NATIVE_HAS_FLAG(wn, WantSetProperty)) {
JSAutoCompartment ac(cx, holder);
bool retval = true;
nsresult rv = wn->GetScriptableCallback()->SetProperty(wn, cx, wrapper,
id, vp.address(), &retval);
if (NS_FAILED(rv) || !retval) {
if (retval)
XPCThrower::Throw(rv, cx);
return false;
}
}
return true;
}
class AutoSetWrapperNotShadowing
{
public:
explicit AutoSetWrapperNotShadowing(ResolvingId *resolvingId MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
MOZ_ASSERT(resolvingId);
mResolvingId = resolvingId;
mResolvingId->mXrayShadowing = true;
}
~AutoSetWrapperNotShadowing()
{
mResolvingId->mXrayShadowing = false;
}
private:
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
ResolvingId *mResolvingId;
};
// This is called after the resolveNativeProperty could not find any property
// with the given id. At this point we can check for DOM specific collections
// like document["formName"] because we already know that it is not shadowing
// any native property.
bool
XPCWrappedNativeXrayTraits::resolveDOMCollectionProperty(JSContext *cx, HandleObject wrapper,
HandleObject holder, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
{
// If we are not currently resolving this id and resolveNative is called
// we don't do anything. (see defineProperty in case of shadowing is forbidden).
ResolvingId *rid = ResolvingId::getResolvingId(holder);
if (!rid || rid->mId != id)
return true;
XPCWrappedNative *wn = getWN(wrapper);
if (!wn) {
// This should NEVER happen, but let's be extra careful here
// because of the reported crashes (Bug 832091).
XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx);
return false;
}
if (!NATIVE_HAS_FLAG(wn, WantNewResolve))
return true;
ResolvingId *resolvingId = ResolvingId::getResolvingIdFromWrapper(wrapper);
if (!resolvingId) {
// This should NEVER happen, but let's be extra careful here
// becaue of the reported crashes (Bug 832091).
XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx);
return false;
}
// Setting the current ResolvingId in non-shadowing mode. So for this id
// Xray won't ignore DOM specific collection properties temporarily.
AutoSetWrapperNotShadowing asw(resolvingId);
bool retval = true;
RootedObject pobj(cx);
nsresult rv = wn->GetScriptableInfo()->GetCallback()->NewResolve(wn, cx, wrapper, id,
pobj.address(), &retval);
if (NS_FAILED(rv)) {
if (retval)
XPCThrower::Throw(rv, cx);
return false;
}
if (pobj && !JS_GetPropertyDescriptorById(cx, holder, id, desc))
return false;
return true;
}
static nsGlobalWindow*
AsWindow(JSContext *cx, JSObject *wrapper)
{
@ -1285,14 +1091,9 @@ XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, HandleObject wr
XPCCallContext ccx(JS_CALLER, cx, target, NullPtr(), id);
// There are no native numeric (or symbol-keyed) properties, so we can
// shortcut here. We will not find the property. However we want to support
// non shadowing dom specific collection properties like window.frames, so
// we still have to check for those.
if (!JSID_IS_STRING(id)) {
/* Not found */
return resolveDOMCollectionProperty(cx, wrapper, holder, id, desc);
}
// shortcut here. We will not find the property.
if (!JSID_IS_STRING(id))
return true;
// The |controllers| property is accessible as a [ChromeOnly] property on
// Window.WebIDL, and [noscript] in XPIDL. Chrome needs to see this over
@ -1346,15 +1147,12 @@ XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, HandleObject wr
XPCWrappedNative *wn = getWN(wrapper);
if (ccx.GetWrapper() != wn || !wn->IsValid()) {
// Something is wrong. If the wrapper is not even valid let's not risk
// calling resolveDOMCollectionProperty.
return true;
} else if (!(iface = ccx.GetInterface()) ||
!(member = ccx.GetMember())) {
/* Not found */
return resolveDOMCollectionProperty(cx, wrapper, holder, id, desc);
}
if (!(iface = ccx.GetInterface()) || !(member = ccx.GetMember()))
return true;
desc.object().set(holder);
desc.setAttributes(JSPROP_ENUMERATE);
desc.setGetter(nullptr);
@ -1541,45 +1339,6 @@ XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsW
// in the wrapper's compartment here, not the wrappee.
MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));
bool hasProp;
if (!JS_HasPropertyById(cx, holder, id, &hasProp)) {
return false;
}
if (!hasProp) {
XPCWrappedNative *wn = getWN(wrapper);
// Run the resolve hook of the wrapped native.
if (!NATIVE_HAS_FLAG(wn, WantNewResolve)) {
return true;
}
bool retval = true;
RootedObject pobj(cx);
nsIXPCScriptable *callback = wn->GetScriptableInfo()->GetCallback();
nsresult rv = callback->NewResolve(wn, cx, wrapper, id, pobj.address(),
&retval);
if (NS_FAILED(rv)) {
if (retval)
XPCThrower::Throw(rv, cx);
return false;
}
MOZ_ASSERT(!pobj || (JS_HasPropertyById(cx, holder, id, &hasProp) &&
hasProp), "id got defined somewhere else?");
}
// resolveOwnProperty must return a non-empty |desc| if and only if an |own|
// property was found on the object. However, given how the NewResolve setup
// works, we can't run the resolve hook if the holder already has a property
// of the same name. So if there was a pre-existing property on the holder,
// we have to use it. But we have no way of knowing if it corresponded to an
// |own| or non-|own| property, since both get cached on the holder and the
// |own|-ness information is lost.
//
// So we just over-zealously call things |own| here. This can cause us to
// return non-|own| properties from Object.getOwnPropertyDescriptor if
// lookups are performed in a certain order, but we can probably live with
// that until XPCWN Xrays go away with the new DOM bindings.
return JS_GetPropertyDescriptorById(cx, holder, id, desc);
}
@ -1590,18 +1349,6 @@ XPCWrappedNativeXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper,
{
*defined = false;
RootedObject holder(cx, singleton.ensureHolder(cx, wrapper));
if (isResolving(cx, holder, id)) {
if (!desc.hasAttributes(JSPROP_GETTER | JSPROP_SETTER)) {
if (!desc.getter())
desc.setGetter(holder_get);
if (!desc.setter())
desc.setSetter(holder_set);
}
*defined = true;
return JS_DefinePropertyById(cx, holder, id, desc.value(), desc.attributes(),
desc.getter(), desc.setter());
}
// Check for an indexed property on a Window. If that's happening, do
// nothing but claim we defined it so it won't get added as an expando.
@ -1647,13 +1394,7 @@ JSObject *
XPCWrappedNativeXrayTraits::createHolder(JSContext *cx, JSObject *wrapper)
{
RootedObject global(cx, JS_GetGlobalForObject(cx, wrapper));
JSObject *holder = JS_NewObjectWithGivenProto(cx, &HolderClass, JS::NullPtr(),
global);
if (!holder)
return nullptr;
js::SetReservedSlot(holder, JSSLOT_RESOLVING, PrivateValue(nullptr));
return holder;
return JS_NewObjectWithGivenProto(cx, &HolderClass, JS::NullPtr(), global);
}
bool
@ -1661,7 +1402,7 @@ XPCWrappedNativeXrayTraits::call(JSContext *cx, HandleObject wrapper,
const JS::CallArgs &args,
const js::Wrapper& baseInstance)
{
// Run the resolve hook of the wrapped native.
// Run the call hook of the wrapped native.
XPCWrappedNative *wn = getWN(wrapper);
if (NATIVE_HAS_FLAG(wn, WantCall)) {
XPCCallContext ccx(JS_CALLER, cx, wrapper, NullPtr(), JSID_VOIDHANDLE, args.length(),
@ -1687,7 +1428,7 @@ XPCWrappedNativeXrayTraits::construct(JSContext *cx, HandleObject wrapper,
const JS::CallArgs &args,
const js::Wrapper& baseInstance)
{
// Run the resolve hook of the wrapped native.
// Run the construct hook of the wrapped native.
XPCWrappedNative *wn = getWN(wrapper);
if (NATIVE_HAS_FLAG(wn, WantConstruct)) {
XPCCallContext ccx(JS_CALLER, cx, wrapper, NullPtr(), JSID_VOIDHANDLE, args.length(),
@ -1910,19 +1651,6 @@ GetNativePropertiesObject(JSContext *cx, JSObject *wrapper)
return holder;
}
bool
IsXrayResolving(JSContext *cx, HandleObject wrapper, HandleId id)
{
if (!WrapperFactory::IsXrayWrapper(wrapper) ||
GetXrayType(wrapper) != XrayForWrappedNative)
{
return false;
}
JSObject *holder =
XPCWrappedNativeXrayTraits::singleton.ensureHolder(cx, wrapper);
return XPCWrappedNativeXrayTraits::isResolving(cx, holder, id);
}
bool
HasNativeProperty(JSContext *cx, HandleObject wrapper, HandleId id, bool *hasProp)
{
@ -1936,9 +1664,6 @@ HasNativeProperty(JSContext *cx, HandleObject wrapper, HandleId id, bool *hasPro
const Wrapper *handler = Wrapper::wrapperHandler(wrapper);
// Try resolveOwnProperty.
Maybe<ResolvingId> resolvingId;
if (traits == &XPCWrappedNativeXrayTraits::singleton)
resolvingId.emplace(cx, wrapper, id);
if (!traits->resolveOwnProperty(cx, *handler, wrapper, holder, id, &desc))
return false;
if (desc.object()) {
@ -2085,12 +1810,6 @@ XrayWrapper<Base, Traits>::getPropertyDescriptor(JSContext *cx, HandleObject wra
assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::GET | BaseProxyHandler::SET |
BaseProxyHandler::GET_PROPERTY_DESCRIPTOR);
RootedObject holder(cx, Traits::singleton.ensureHolder(cx, wrapper));
if (Traits::isResolving(cx, holder, id)) {
desc.object().set(nullptr);
return true;
}
typename Traits::ResolvingIdImpl resolving(cx, wrapper, id);
if (!holder)
return false;
@ -2218,15 +1937,6 @@ XrayWrapper<Base, Traits>::getOwnPropertyDescriptor(JSContext *cx, HandleObject
assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::GET | BaseProxyHandler::SET |
BaseProxyHandler::GET_PROPERTY_DESCRIPTOR);
RootedObject holder(cx, Traits::singleton.ensureHolder(cx, wrapper));
if (Traits::isResolving(cx, holder, id)) {
desc.object().set(nullptr);
return true;
}
typename Traits::ResolvingIdImpl resolving(cx, wrapper, id);
// NB: Nothing we do here acts on the wrapped native itself, so we don't
// enter our policy.
if (!Traits::singleton.resolveOwnProperty(cx, *this, wrapper, holder, id, desc))
return false;

View File

@ -24,12 +24,6 @@ class XPCWrappedNative;
namespace xpc {
bool
holder_get(JSContext *cx, JS::HandleObject holder, JS::HandleId id, JS::MutableHandleValue vp);
bool
holder_set(JSContext *cx, JS::HandleObject holder, JS::HandleId id, bool strict,
JS::MutableHandleValue vp);
namespace XrayUtils {
bool IsXPCWNHolderClass(const JSClass *clasp);
@ -42,9 +36,6 @@ IsTransparent(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id);
JSObject *
GetNativePropertiesObject(JSContext *cx, JSObject *wrapper);
bool
IsXrayResolving(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id);
bool
HasNativeProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
bool *hasProp);
@ -58,35 +49,6 @@ enum XrayType {
NotXray
};
class MOZ_STACK_CLASS ResolvingId {
public:
ResolvingId(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id);
~ResolvingId();
bool isXrayShadowing(jsid id);
bool isResolving(jsid id);
static ResolvingId* getResolvingId(JSObject *holder);
static JSObject* getHolderObject(JSObject *wrapper);
static ResolvingId *getResolvingIdFromWrapper(JSObject *wrapper);
private:
friend class AutoSetWrapperNotShadowing;
friend class XPCWrappedNativeXrayTraits;
JS::HandleId mId;
JS::RootedObject mHolder;
ResolvingId *mPrev;
bool mXrayShadowing;
};
class MOZ_STACK_CLASS ResolvingIdDummy
{
public:
ResolvingIdDummy(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id)
{
}
};
class XrayTraits
{
public:
@ -174,8 +136,6 @@ public:
static bool construct(JSContext *cx, JS::HandleObject wrapper,
const JS::CallArgs &args, const js::Wrapper& baseInstance);
static bool isResolving(JSContext *cx, JSObject *holder, jsid id);
static bool resolveDOMCollectionProperty(JSContext *cx, JS::HandleObject wrapper,
JS::HandleObject holder, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
@ -184,8 +144,6 @@ public:
virtual void preserveWrapper(JSObject *target) MOZ_OVERRIDE;
typedef ResolvingId ResolvingIdImpl;
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
static const JSClass HolderClass;
@ -219,13 +177,6 @@ public:
static bool construct(JSContext *cx, JS::HandleObject wrapper,
const JS::CallArgs &args, const js::Wrapper& baseInstance);
static bool isResolving(JSContext *cx, JSObject *holder, jsid id)
{
return false;
}
typedef ResolvingIdDummy ResolvingIdImpl;
virtual void preserveWrapper(JSObject *target) MOZ_OVERRIDE;
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
@ -287,13 +238,6 @@ public:
return false;
}
static bool isResolving(JSContext *cx, JSObject *holder, jsid id)
{
return false;
}
typedef ResolvingIdDummy ResolvingIdImpl;
bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper,
JS::HandleObject target,
JS::MutableHandleObject protop)
@ -408,13 +352,6 @@ public:
return false;
}
static bool isResolving(JSContext *cx, JSObject *holder, jsid id)
{
return false;
}
typedef ResolvingIdDummy ResolvingIdImpl;
bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper,
JS::HandleObject target,
JS::MutableHandleObject protop)

View File

@ -9,6 +9,7 @@
#include <ctime>
#include "mozilla/DebugOnly.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/MathAlgorithms.h"
@ -3598,8 +3599,8 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
}
gfxContext *ctx = aContext.ThebesContext();
gfxContext::AntialiasMode oldMode = ctx->CurrentAntialiasMode();
ctx->SetAntialiasMode(gfxContext::MODE_ALIASED);
AntialiasMode oldMode = ctx->CurrentAntialiasMode();
ctx->SetAntialiasMode(AntialiasMode::NONE);
switch (aBorderStyle) {
case NS_STYLE_BORDER_STYLE_NONE:
@ -3932,12 +3933,12 @@ nsCSSRendering::PaintDecorationLine(nsIFrame* aFrame,
contextIsSaved = true;
aGfxContext->Clip(rect);
if (lineHeight > 2.0) {
aGfxContext->SetAntialiasMode(gfxContext::MODE_COVERAGE);
aGfxContext->SetAntialiasMode(AntialiasMode::SUBPIXEL);
} else {
// Don't use anti-aliasing here. Because looks like lighter color wavy
// line at this case. And probably, users don't think the
// non-anti-aliased wavy line is not pretty.
aGfxContext->SetAntialiasMode(gfxContext::MODE_ALIASED);
aGfxContext->SetAntialiasMode(AntialiasMode::NONE);
}
break;
default:

View File

@ -1494,7 +1494,7 @@ nsCSSBorderRenderer::DrawBorders()
gfxFloat dash = mBorderWidths[0];
mContext->SetDash(&dash, 1, 0.5);
mContext->SetAntialiasMode(gfxContext::MODE_ALIASED);
mContext->SetAntialiasMode(AntialiasMode::NONE);
gfxRect rect = mOuterRect;
rect.Deflate(mBorderWidths[0] / 2.0);
mContext->NewPath();

View File

@ -6726,9 +6726,27 @@ bool
ClusterIterator::IsPunctuation()
{
NS_ASSERTION(mCharIndex >= 0, "No cluster selected");
nsIUGenCategory::nsUGenCategory c =
mozilla::unicode::GetGenCategory(mFrag->CharAt(mCharIndex));
return c == nsIUGenCategory::kPunctuation || c == nsIUGenCategory::kSymbol;
// Return true for all Punctuation categories (Unicode general category P?),
// and also for Symbol categories (S?) except for Modifier Symbol, which is
// kept together with any adjacent letter/number. (Bug 1066756)
uint8_t cat = unicode::GetGeneralCategory(mFrag->CharAt(mCharIndex));
switch (cat) {
case HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION: /* Pc */
case HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION: /* Pd */
case HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION: /* Pe */
case HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION: /* Pf */
case HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION: /* Pi */
case HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION: /* Po */
case HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION: /* Ps */
case HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL: /* Sc */
// Deliberately omitted:
// case HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL: /* Sk */
case HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL: /* Sm */
case HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL: /* So */
return true;
default:
return false;
}
}
int32_t

View File

@ -14,7 +14,7 @@
<p id="catch">Catch-all
<pre id="test"><script class="testbody" type="text/javascript;version=1.7">
/** Tests for bugs 384147 and 981281 **/
/** Tests for bugs 384147, 981281, 1066756 **/
SimpleTest.waitForExplicitFinish();
@ -63,7 +63,8 @@ var ChineseChars = "&#x6F22;&#x5B57;";
var HiraganaChars = "&#x3072;&#x3089;&#x304C;&#x306A;";
var KatakanaChars = "&#x30AB;&#x30BF;&#x30AB;&#x30CA;";
var JapaneseFullStop = "&#x3002;";
var JapaneseComma = "&#x3001";
var JapaneseComma = "&#x3001;";
var ModifierColon = "&#xA789;";
function test() {
setPrefs(false, true, test1);
@ -176,6 +177,14 @@ function test1() {
testLeft(editor.firstChild, 3);
testLeft(editor.firstChild, 0);
// test for bug 1066756
editor.innerHTML = "hello" + ModifierColon + " wo" + ModifierColon + "rld";
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 6);
testRight(editor.firstChild, 13);
testLeft(editor.firstChild, 7);
testLeft(editor.firstChild, 0);
// test basic word movement with eat_space_next_to_word true.
setPrefs(true, true, test2);
}
@ -285,6 +294,13 @@ function test2() {
testLeft(editor.firstChild, 3);
testLeft(editor.firstChild, 0);
editor.innerHTML = "hello" + ModifierColon + " wo" + ModifierColon + "rld";
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 7);
testRight(editor.firstChild, 13);
testLeft(editor.firstChild, 7);
testLeft(editor.firstChild, 0);
// Test basic word movement with stop_at_punctuation false (bug 981281).
setPrefs(false, false, test3);
}
@ -378,6 +394,13 @@ function test3() {
testRight(editor.firstChild, 8);
testLeft(editor.firstChild, 0);
editor.innerHTML = "hello" + ModifierColon + " wo" + ModifierColon + "rld";
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 6);
testRight(editor.firstChild, 13);
testLeft(editor.firstChild, 7);
testLeft(editor.firstChild, 0);
// And again with eat_space_next_to_word true.
setPrefs(true, false, test4);
}
@ -471,6 +494,13 @@ function test4() {
testRight(editor.firstChild, 8);
testLeft(editor.firstChild, 0);
editor.innerHTML = "hello" + ModifierColon + " wo" + ModifierColon + "rld";
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 7);
testRight(editor.firstChild, 13);
testLeft(editor.firstChild, 7);
testLeft(editor.firstChild, 0);
SimpleTest.finish();
}

View File

@ -0,0 +1,37 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Filters: Hue Rotate an HTML Element Containing Colors with Multiple RGB Channels</title>
<link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
<style type="text/css">
#target {
width: 150px;
height: 150px;
}
.color-strip {
height: 50px;
}
#color-strip-1 {
background-color: rgb(64, 187, 46);
}
#color-strip-2 {
background-color: rgb(64, 250, 255);
}
#color-strip-3 {
background-color: rgb(255, 14, 109);
}
</style>
</head>
<body>
<p>You should see a horizontal green strip, followed by a cyan strip, followed by a magenta strip.</p>
<div id="target">
<div id="color-strip-1" class="color-strip"></div>
<div id="color-strip-2" class="color-strip"></div>
<div id="color-strip-3" class="color-strip"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Filters: Hue Rotate an HTML Element Containing Colors with Multiple RGB Channels</title>
<link rel="author" title="Max Vujovic" href="mailto:mvujovic@adobe.com">
<style type="text/css">
#target {
filter: hue-rotate(90deg);
width: 150px;
height: 150px;
}
.color-strip {
height: 50px;
}
#color-strip-1 {
background-color: rgb(255, 128, 64);
}
#color-strip-2 {
background-color: rgb(128, 255, 64);
}
#color-strip-3 {
background-color: rgb(32, 64, 255);
}
</style>
</head>
<body>
<p>You should see a horizontal green strip, followed by a cyan strip, followed by a magenta strip.</p>
<div id="target">
<div id="color-strip-1" class="color-strip"></div>
<div id="color-strip-2" class="color-strip"></div>
<div id="color-strip-3" class="color-strip"></div>
</div>
</body>
</html>

View File

@ -36,6 +36,7 @@ fuzzy-if(d2d,1,10000) == grayscale-percent.html grayscale-percent-ref.html
== hue-rotate.html hue-rotate-ref.html
== hue-rotate-360.html hue-rotate-360-ref.html
== hue-rotate-grad.html hue-rotate-grad-ref.html
fuzzy-if(d2d,2,7500) == hue-rotate-multichannel.html hue-rotate-multichannel-ref.html
== hue-rotate-negative.html hue-rotate-negative-ref.html
== hue-rotate-over-360.html hue-rotate-over-360-ref.html
== hue-rotate-rad.html hue-rotate-rad-ref.html

View File

@ -2888,10 +2888,10 @@ SVGTextDrawPathCallbacks::SetupContext()
// or make SetAntialiasMode set cairo text antialiasing too.
switch (mFrame->StyleSVG()->mTextRendering) {
case NS_STYLE_TEXT_RENDERING_OPTIMIZESPEED:
gfx->SetAntialiasMode(gfxContext::MODE_ALIASED);
gfx->SetAntialiasMode(AntialiasMode::NONE);
break;
default:
gfx->SetAntialiasMode(gfxContext::MODE_COVERAGE);
gfx->SetAntialiasMode(AntialiasMode::SUBPIXEL);
break;
}
}

View File

@ -29,11 +29,11 @@ static float ClampFactor(float aFactor)
}
nsCSSFilterInstance::nsCSSFilterInstance(const nsStyleFilter& aFilter,
nsIFrame *aTargetFrame,
nscolor aShadowFallbackColor,
const nsIntRect& aTargetBBoxInFilterSpace,
const gfxMatrix& aFrameSpaceInCSSPxToFilterSpaceTransform)
: mFilter(aFilter)
, mTargetFrame(aTargetFrame)
, mShadowFallbackColor(aShadowFallbackColor)
, mTargetBBoxInFilterSpace(aTargetBBoxInFilterSpace)
, mFrameSpaceInCSSPxToFilterSpaceTransform(aFrameSpaceInCSSPxToFilterSpaceTransform)
{
@ -201,8 +201,7 @@ nsCSSFilterInstance::SetAttributesForDropShadow(FilterPrimitiveDescription& aDes
aDescr.Attributes().Set(eDropShadowOffset, offsetInFilterSpace);
// Set color. If unspecified, use the CSS color property.
nscolor shadowColor = shadow->mHasColor ?
shadow->mColor : mTargetFrame->StyleColor()->mColor;
nscolor shadowColor = shadow->mHasColor ? shadow->mColor : mShadowFallbackColor;
aDescr.Attributes().Set(eDropShadowColor, ToAttributeColor(shadowColor));
return NS_OK;

View File

@ -35,14 +35,16 @@ public:
* @param aFilter The CSS filter from the style system. This class stores
* aFilter by reference, so callers should avoid modifying or deleting
* aFilter during the lifetime of nsCSSFilterInstance.
* @param mTargetBBoxInFilterSpace The frame of element being filtered, in
* @param aShadowFallbackColor The color that should be used for
* drop-shadow() filters that don't specify a shadow color.
* @param aTargetBBoxInFilterSpace The frame of element being filtered, in
* filter space.
* @param aFrameSpaceInCSSPxToFilterSpaceTransform The transformation from
* the filtered element's frame space in CSS pixels to filter space.
*/
nsCSSFilterInstance(const nsStyleFilter& aFilter,
nsIFrame *aTargetFrame,
const nsIntRect& mTargetBBoxInFilterSpace,
nscolor aShadowFallbackColor,
const nsIntRect& aTargetBBoxInFilterSpace,
const gfxMatrix& aFrameSpaceInCSSPxToFilterSpaceTransform);
/**
@ -112,9 +114,10 @@ private:
const nsStyleFilter& mFilter;
/**
* The frame for the element that is currently being filtered.
* The color that should be used for drop-shadow() filters that don't
* specify a shadow color.
*/
nsIFrame* mTargetFrame;
nscolor mShadowFallbackColor;
/**
* The bounding box of the element being filtered, in filter space. Used for

View File

@ -6,6 +6,9 @@
// Main header first:
#include "nsFilterInstance.h"
// MFBT headers next:
#include "mozilla/UniquePtr.h"
// Keep others in (case-insensitive) order:
#include "gfxPlatform.h"
#include "gfxUtils.h"
@ -24,6 +27,33 @@ using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::gfx;
FilterDescription
nsFilterInstance::GetFilterDescription(nsIContent* aFilteredElement,
const nsTArray<nsStyleFilter>& aFilterChain,
const UserSpaceMetrics& aMetrics,
const gfxRect& aBBox,
nsTArray<mozilla::RefPtr<SourceSurface>>& aOutAdditionalImages)
{
gfxMatrix unused; // aPaintTransform arg not used since we're not painting
nsFilterInstance instance(nullptr, aFilteredElement, aMetrics,
aFilterChain, nullptr, unused,
nullptr, nullptr, nullptr, &aBBox);
if (!instance.IsInitialized()) {
return FilterDescription();
}
return instance.ExtractDescriptionAndAdditionalImages(aOutAdditionalImages);
}
static UniquePtr<UserSpaceMetrics>
UserSpaceMetricsForFrame(nsIFrame* aFrame)
{
if (aFrame->GetContent()->IsSVG()) {
nsSVGElement* element = static_cast<nsSVGElement*>(aFrame->GetContent());
return MakeUnique<SVGElementMetrics>(element);
}
return MakeUnique<NonSVGFrameUserSpaceMetrics>(aFrame);
}
nsresult
nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame,
nsRenderingContext *aContext,
@ -31,7 +61,10 @@ nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame,
nsSVGFilterPaintCallback *aPaintCallback,
const nsRegion *aDirtyArea)
{
nsFilterInstance instance(aFilteredFrame, aPaintCallback, aTransform,
auto& filterChain = aFilteredFrame->StyleSVGReset()->mFilters;
UniquePtr<UserSpaceMetrics> metrics = UserSpaceMetricsForFrame(aFilteredFrame);
nsFilterInstance instance(aFilteredFrame, aFilteredFrame->GetContent(), *metrics,
filterChain, aPaintCallback, aTransform,
aDirtyArea, nullptr, nullptr, nullptr);
if (!instance.IsInitialized()) {
return NS_OK;
@ -48,7 +81,10 @@ nsFilterInstance::GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
}
gfxMatrix unused; // aPaintTransform arg not used since we're not painting
nsFilterInstance instance(aFilteredFrame, nullptr, unused, nullptr,
auto& filterChain = aFilteredFrame->StyleSVGReset()->mFilters;
UniquePtr<UserSpaceMetrics> metrics = UserSpaceMetricsForFrame(aFilteredFrame);
nsFilterInstance instance(aFilteredFrame, aFilteredFrame->GetContent(), *metrics,
filterChain, nullptr, unused, nullptr,
&aPreFilterDirtyRegion);
if (!instance.IsInitialized()) {
return nsRegion();
@ -65,7 +101,10 @@ nsFilterInstance::GetPreFilterNeededArea(nsIFrame *aFilteredFrame,
const nsRegion& aPostFilterDirtyRegion)
{
gfxMatrix unused; // aPaintTransform arg not used since we're not painting
nsFilterInstance instance(aFilteredFrame, nullptr, unused,
auto& filterChain = aFilteredFrame->StyleSVGReset()->mFilters;
UniquePtr<UserSpaceMetrics> metrics = UserSpaceMetricsForFrame(aFilteredFrame);
nsFilterInstance instance(aFilteredFrame, aFilteredFrame->GetContent(), *metrics,
filterChain, nullptr, unused,
&aPostFilterDirtyRegion);
if (!instance.IsInitialized()) {
return nsRect();
@ -93,7 +132,10 @@ nsFilterInstance::GetPostFilterBounds(nsIFrame *aFilteredFrame,
}
gfxMatrix unused; // aPaintTransform arg not used since we're not painting
nsFilterInstance instance(aFilteredFrame, nullptr, unused, nullptr,
auto& filterChain = aFilteredFrame->StyleSVGReset()->mFilters;
UniquePtr<UserSpaceMetrics> metrics = UserSpaceMetricsForFrame(aFilteredFrame);
nsFilterInstance instance(aFilteredFrame, aFilteredFrame->GetContent(), *metrics,
filterChain, nullptr, unused, nullptr,
preFilterRegionPtr, aPreFilterBounds,
aOverrideBBox);
if (!instance.IsInitialized()) {
@ -104,6 +146,9 @@ nsFilterInstance::GetPostFilterBounds(nsIFrame *aFilteredFrame,
}
nsFilterInstance::nsFilterInstance(nsIFrame *aTargetFrame,
nsIContent* aTargetContent,
const UserSpaceMetrics& aMetrics,
const nsTArray<nsStyleFilter>& aFilterChain,
nsSVGFilterPaintCallback *aPaintCallback,
const gfxMatrix& aPaintTransform,
const nsRegion *aPostFilterDirtyRegion,
@ -111,13 +156,18 @@ nsFilterInstance::nsFilterInstance(nsIFrame *aTargetFrame,
const nsRect *aPreFilterVisualOverflowRectOverride,
const gfxRect *aOverrideBBox)
: mTargetFrame(aTargetFrame)
, mTargetContent(aTargetContent)
, mMetrics(aMetrics)
, mPaintCallback(aPaintCallback)
, mPaintTransform(aPaintTransform)
, mInitialized(false)
{
mTargetBBox = aOverrideBBox ?
*aOverrideBBox : nsSVGUtils::GetBBox(mTargetFrame);
if (aOverrideBBox) {
mTargetBBox = *aOverrideBBox;
} else {
MOZ_ASSERT(mTargetFrame, "Need to supply a frame when there's no aOverrideBBox");
mTargetBBox = nsSVGUtils::GetBBox(mTargetFrame);
}
// Compute user space to filter space transforms.
nsresult rv = ComputeUserSpaceToFilterSpaceScale();
@ -151,7 +201,7 @@ nsFilterInstance::nsFilterInstance(nsIFrame *aTargetFrame,
mFrameSpaceInCSSPxToFilterSpaceTransform.Invert();
// Build the filter graph.
rv = BuildPrimitives();
rv = BuildPrimitives(aFilterChain);
if (NS_FAILED(rv)) {
return;
}
@ -164,13 +214,16 @@ nsFilterInstance::nsFilterInstance(nsIFrame *aTargetFrame,
// Convert the passed in rects from frame space to filter space:
mPostFilterDirtyRegion = FrameSpaceToFilterSpace(aPostFilterDirtyRegion);
mPreFilterDirtyRegion = FrameSpaceToFilterSpace(aPreFilterDirtyRegion);
nsIntRect targetBounds;
if (aPreFilterVisualOverflowRectOverride) {
mTargetBounds =
targetBounds =
FrameSpaceToFilterSpace(aPreFilterVisualOverflowRectOverride);
} else {
} else if (mTargetFrame) {
nsRect preFilterVOR = mTargetFrame->GetPreEffectsVisualOverflowRect();
mTargetBounds = FrameSpaceToFilterSpace(&preFilterVOR);
targetBounds = FrameSpaceToFilterSpace(&preFilterVOR);
}
mTargetBounds.UnionRect(mTargetBBoxInFilterSpace, targetBounds);
mInitialized = true;
}
@ -178,10 +231,13 @@ nsFilterInstance::nsFilterInstance(nsIFrame *aTargetFrame,
nsresult
nsFilterInstance::ComputeUserSpaceToFilterSpaceScale()
{
gfxMatrix canvasTransform = nsSVGUtils::GetCanvasTM(mTargetFrame);
if (canvasTransform.IsSingular()) {
// Nothing should be rendered.
return NS_ERROR_FAILURE;
gfxMatrix canvasTransform;
if (mTargetFrame) {
canvasTransform = nsSVGUtils::GetCanvasTM(mTargetFrame);
if (canvasTransform.IsSingular()) {
// Nothing should be rendered.
return NS_ERROR_FAILURE;
}
}
mUserSpaceToFilterSpaceScale = canvasTransform.ScaleFactors(true);
@ -215,14 +271,13 @@ nsFilterInstance::FilterSpaceToUserSpace(const gfxRect& aFilterSpaceRect) const
}
nsresult
nsFilterInstance::BuildPrimitives()
nsFilterInstance::BuildPrimitives(const nsTArray<nsStyleFilter>& aFilterChain)
{
NS_ASSERTION(!mPrimitiveDescriptions.Length(),
"expected to start building primitives from scratch");
const nsTArray<nsStyleFilter>& filters = mTargetFrame->StyleSVGReset()->mFilters;
for (uint32_t i = 0; i < filters.Length(); i++) {
nsresult rv = BuildPrimitivesForFilter(filters[i]);
for (uint32_t i = 0; i < aFilterChain.Length(); i++) {
nsresult rv = BuildPrimitivesForFilter(aFilterChain[i]);
if (NS_FAILED(rv)) {
return rv;
}
@ -242,7 +297,8 @@ nsFilterInstance::BuildPrimitivesForFilter(const nsStyleFilter& aFilter)
if (aFilter.GetType() == NS_STYLE_FILTER_URL) {
// Build primitives for an SVG filter.
nsSVGFilterInstance svgFilterInstance(aFilter, mTargetFrame, mTargetBBox,
nsSVGFilterInstance svgFilterInstance(aFilter, mTargetContent,
mMetrics, mTargetBBox,
mUserSpaceToFilterSpaceScale,
mFilterSpaceToUserSpaceScale);
if (!svgFilterInstance.IsInitialized()) {
@ -253,7 +309,13 @@ nsFilterInstance::BuildPrimitivesForFilter(const nsStyleFilter& aFilter)
}
// Build primitives for a CSS filter.
nsCSSFilterInstance cssFilterInstance(aFilter, mTargetFrame,
// If we don't have a frame, use opaque black for shadows with unspecified
// shadow colors.
nscolor shadowFallbackColor =
mTargetFrame ? mTargetFrame->StyleColor()->mColor : NS_RGB(0,0,0);
nsCSSFilterInstance cssFilterInstance(aFilter, shadowFallbackColor,
mTargetBBoxInFilterSpace,
mFrameSpaceInCSSPxToFilterSpaceTransform);
return cssFilterInstance.BuildPrimitives(mPrimitiveDescriptions);
@ -273,10 +335,7 @@ nsFilterInstance::ComputeNeededBoxes()
mFilterDescription, mPostFilterDirtyRegion,
sourceGraphicNeededRegion, fillPaintNeededRegion, strokePaintNeededRegion);
nsIntRect sourceBounds;
sourceBounds.UnionRect(mTargetBBoxInFilterSpace, mTargetBounds);
sourceGraphicNeededRegion.And(sourceGraphicNeededRegion, sourceBounds);
sourceGraphicNeededRegion.And(sourceGraphicNeededRegion, mTargetBounds);
mSourceGraphic.mNeededBounds = sourceGraphicNeededRegion.GetBounds();
mFillPaint.mNeededBounds = fillPaintNeededRegion.GetBounds();
@ -287,6 +346,7 @@ nsresult
nsFilterInstance::BuildSourcePaint(SourceInfo *aSource,
DrawTarget* aTargetDT)
{
MOZ_ASSERT(mTargetFrame);
nsIntRect neededRect = aSource->mNeededBounds;
RefPtr<DrawTarget> offscreenDT =
@ -344,6 +404,8 @@ nsFilterInstance::BuildSourcePaints(DrawTarget* aTargetDT)
nsresult
nsFilterInstance::BuildSourceImage(DrawTarget* aTargetDT)
{
MOZ_ASSERT(mTargetFrame);
nsIntRect neededRect = mSourceGraphic.mNeededBounds;
if (neededRect.IsEmpty()) {
return NS_OK;
@ -395,6 +457,8 @@ nsFilterInstance::BuildSourceImage(DrawTarget* aTargetDT)
nsresult
nsFilterInstance::Render(gfxContext* aContext)
{
MOZ_ASSERT(mTargetFrame, "Need a frame for rendering");
nsIntRect filterRect = mPostFilterDirtyRegion.GetBounds().Intersect(OutputFilterSpaceBounds());
gfxMatrix ctm = GetFilterSpaceToDeviceSpaceTransform();
@ -443,11 +507,8 @@ nsFilterInstance::ComputePostFilterDirtyRegion()
nsRect
nsFilterInstance::ComputePostFilterExtents()
{
nsIntRect sourceBounds;
sourceBounds.UnionRect(mTargetBBoxInFilterSpace, mTargetBounds);
nsIntRegion postFilterExtents =
FilterSupport::ComputePostFilterExtents(mFilterDescription, sourceBounds);
FilterSupport::ComputePostFilterExtents(mFilterDescription, mTargetBounds);
return FilterSpaceToFrameSpace(postFilterExtents.GetBounds());
}
@ -537,5 +598,8 @@ nsFilterInstance::FilterSpaceToFrameSpace(const nsIntRegion& aRegion) const
gfxMatrix
nsFilterInstance::GetUserSpaceToFrameSpaceInCSSPxTransform() const
{
if (!mTargetFrame) {
return gfxMatrix();
}
return gfxMatrix::Translation(-nsSVGUtils::FrameSpaceInCSSPxToUserSpaceOffset(mTargetFrame));
}

View File

@ -25,6 +25,12 @@ class gfxASurface;
class nsIFrame;
class nsSVGFilterPaintCallback;
namespace mozilla {
namespace dom {
class UserSpaceMetrics;
}
}
/**
* This class performs all filter processing.
*
@ -48,8 +54,22 @@ class nsFilterInstance
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
typedef mozilla::gfx::FilterDescription FilterDescription;
typedef mozilla::dom::UserSpaceMetrics UserSpaceMetrics;
public:
/**
* Create a FilterDescription for the supplied filter. All coordinates in
* the description are in filter space.
* @param aOutAdditionalImages Will contain additional images needed to
* render the filter (from feImage primitives).
* @return A FilterDescription describing the filter.
*/
static FilterDescription GetFilterDescription(nsIContent* aFilteredElement,
const nsTArray<nsStyleFilter>& aFilterChain,
const UserSpaceMetrics& aMetrics,
const gfxRect& aBBox,
nsTArray<mozilla::RefPtr<SourceSurface>>& aOutAdditionalImages);
/**
* Paint the given filtered frame.
* @param aDirtyArea The area than needs to be painted, in aFilteredFrame's
@ -93,7 +113,11 @@ public:
const nsRect *aPreFilterBounds = nullptr);
/**
* @param aTargetFrame The frame of the filtered element under consideration.
* @param aTargetFrame The frame of the filtered element under consideration,
* may be null.
* @param aTargetContent The filtered element itself.
* @param aMetrics The metrics to resolve SVG lengths against.
* @param aFilterChain The list of filters to apply.
* @param aPaintCallback [optional] The callback that Render() should use to
* paint. Only required if you will call Render().
* @param aPaintTransform The transform to apply to convert to
@ -107,9 +131,12 @@ public:
* @param aOverridePreFilterVisualOverflowRect [optional] Use a different
* visual overflow rect for the target element.
* @param aOverrideBBox [optional] Use a different SVG bbox for the target
* element.
* element. Must be non-null if aTargetFrame is null.
*/
nsFilterInstance(nsIFrame *aTargetFrame,
nsIContent* aTargetContent,
const UserSpaceMetrics& aMetrics,
const nsTArray<nsStyleFilter>& aFilterChain,
nsSVGFilterPaintCallback *aPaintCallback,
const gfxMatrix& aPaintTransform,
const nsRegion *aPostFilterDirtyRegion = nullptr,
@ -130,6 +157,12 @@ public:
*/
nsresult Render(gfxContext* aContext);
const FilterDescription& ExtractDescriptionAndAdditionalImages(nsTArray<mozilla::RefPtr<SourceSurface>>& aOutAdditionalImages)
{
mInputImages.SwapElements(aOutAdditionalImages);
return mFilterDescription;
}
/**
* Sets the aPostFilterDirtyRegion outparam to the post-filter area in frame
* space that would be dirtied by mTargetFrame when a given
@ -205,7 +238,7 @@ private:
* filter primitives and their connections. This populates
* mPrimitiveDescriptions and mInputImages.
*/
nsresult BuildPrimitives();
nsresult BuildPrimitives(const nsTArray<nsStyleFilter>& aFilterChain);
/**
* Add to the list of FilterPrimitiveDescriptions for a particular SVG
@ -267,6 +300,16 @@ private:
*/
nsIFrame* mTargetFrame;
/**
* The filtered element.
*/
nsIContent* mTargetContent;
/**
* The user space metrics of the filtered frame.
*/
const UserSpaceMetrics& mMetrics;
nsSVGFilterPaintCallback* mPaintCallback;
/**

View File

@ -24,12 +24,14 @@ using namespace mozilla::dom;
using namespace mozilla::gfx;
nsSVGFilterInstance::nsSVGFilterInstance(const nsStyleFilter& aFilter,
nsIFrame *aTargetFrame,
nsIContent* aTargetContent,
const UserSpaceMetrics& aMetrics,
const gfxRect& aTargetBBox,
const gfxSize& aUserSpaceToFilterSpaceScale,
const gfxSize& aFilterSpaceToUserSpaceScale) :
mFilter(aFilter),
mTargetFrame(aTargetFrame),
mTargetContent(aTargetContent),
mMetrics(aMetrics),
mTargetBBox(aTargetBBox),
mUserSpaceToFilterSpaceScale(aUserSpaceToFilterSpaceScale),
mFilterSpaceToUserSpaceScale(aFilterSpaceToUserSpaceScale),
@ -86,7 +88,7 @@ nsSVGFilterInstance::ComputeBounds()
uint16_t filterUnits =
mFilterFrame->GetEnumValue(SVGFilterElement::FILTERUNITS);
gfxRect userSpaceBounds = nsSVGUtils::GetRelativeRect(filterUnits,
XYWH, mTargetBBox, mTargetFrame);
XYWH, mTargetBBox, mMetrics);
// Transform the user space bounds to filter space, so we
// can align them with the pixel boundries of the offscreen surface.
@ -126,16 +128,14 @@ nsSVGFilterInstance::GetFilterFrame()
// Get the target element to use as a point of reference for looking up the
// filter element.
nsIContent* targetElement = mTargetFrame->GetContent();
if (!targetElement) {
// There is no element associated with the target frame.
if (!mTargetContent) {
return nullptr;
}
// Look up the filter element by URL.
nsReferencedElement filterElement;
bool watch = false;
filterElement.Reset(targetElement, url, watch);
filterElement.Reset(mTargetContent, url, watch);
Element* element = filterElement.get();
if (!element) {
// The URL points to no element.
@ -144,8 +144,9 @@ nsSVGFilterInstance::GetFilterFrame()
// Get the frame of the filter element.
nsIFrame* frame = element->GetPrimaryFrame();
if (frame->GetType() != nsGkAtoms::svgFilterFrame) {
// The URL points to an element that's not an SVG filter element.
if (!frame || frame->GetType() != nsGkAtoms::svgFilterFrame) {
// The URL points to an element that's not an SVG filter element, or to an
// element that hasn't had its frame constructed yet.
return nullptr;
}
@ -163,7 +164,7 @@ nsSVGFilterInstance::GetPrimitiveNumber(uint8_t aCtxType, float aValue) const
if (mPrimitiveUnits == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
value = nsSVGUtils::ObjectSpace(mTargetBBox, &val);
} else {
value = nsSVGUtils::UserSpace(mTargetFrame, &val);
value = nsSVGUtils::UserSpace(mMetrics, &val);
}
switch (aCtxType) {
@ -194,7 +195,7 @@ nsSVGFilterInstance::ConvertLocation(const Point3D& aPoint) const
nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
gfxRect feArea = nsSVGUtils::GetRelativeRect(mPrimitiveUnits,
val, mTargetBBox, mTargetFrame);
val, mTargetBBox, mMetrics);
gfxRect r = UserSpaceToFilterSpace(feArea);
return Point3D(r.x, r.y, GetPrimitiveNumber(SVGContentUtils::XY, aPoint.z));
}
@ -240,7 +241,7 @@ nsSVGFilterInstance::ComputeFilterPrimitiveSubregion(nsSVGFE* aFilterElement,
}
gfxRect feArea = nsSVGUtils::GetRelativeRect(mPrimitiveUnits,
&fE->mLengthAttributes[nsSVGFE::ATTR_X], mTargetBBox, mTargetFrame);
&fE->mLengthAttributes[nsSVGFE::ATTR_X], mTargetBBox, mMetrics);
Rect region = ToRect(UserSpaceToFilterSpace(feArea));
if (!fE->mLengthAttributes[nsSVGFE::ATTR_X].IsExplicitlySet())
@ -387,7 +388,7 @@ nsSVGFilterInstance::BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrim
nsDataHashtable<nsStringHashKey, int32_t> imageTable(8);
// The principal that we check principals of any loaded images against.
nsCOMPtr<nsIPrincipal> principal = mTargetFrame->GetContent()->NodePrincipal();
nsCOMPtr<nsIPrincipal> principal = mTargetContent->NodePrincipal();
for (uint32_t primitiveElementIndex = 0;
primitiveElementIndex < primitives.Length();

View File

@ -70,18 +70,20 @@ class nsSVGFilterInstance
typedef mozilla::gfx::IntRect IntRect;
typedef mozilla::gfx::SourceSurface SourceSurface;
typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
typedef mozilla::dom::UserSpaceMetrics UserSpaceMetrics;
public:
/**
* @param aFilter The SVG filter reference from the style system. This class
* stores aFilter by reference, so callers should avoid modifying or
* deleting aFilter during the lifetime of nsSVGFilterInstance.
* @param aTargetFrame The frame of the filtered element under consideration.
* @param aTargetContent The filtered element.
* @param aTargetBBox The SVG bbox to use for the target frame, computed by
* the caller. The caller may decide to override the actual SVG bbox.
*/
nsSVGFilterInstance(const nsStyleFilter& aFilter,
nsIFrame *aTargetFrame,
nsIContent* aTargetContent,
const UserSpaceMetrics& aMetrics,
const gfxRect& aTargetBBox,
const gfxSize& aUserSpaceToFilterSpaceScale,
const gfxSize& aFilterSpaceToUserSpaceScale);
@ -208,9 +210,14 @@ private:
const nsStyleFilter& mFilter;
/**
* The frame for the element that is currently being filtered.
* The filtered element.
*/
nsIFrame* mTargetFrame;
nsIContent* mTargetContent;
/**
* The SVG user space metrics that SVG lengths are resolved against.
*/
const UserSpaceMetrics& mMetrics;
/**
* The filter element referenced by mTargetFrame's element.

View File

@ -620,10 +620,10 @@ nsSVGPathGeometryFrame::Render(nsRenderingContext *aContext,
switch (StyleSVG()->mShapeRendering) {
case NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED:
case NS_STYLE_SHAPE_RENDERING_CRISPEDGES:
gfx->SetAntialiasMode(gfxContext::MODE_ALIASED);
gfx->SetAntialiasMode(AntialiasMode::NONE);
break;
default:
gfx->SetAntialiasMode(gfxContext::MODE_COVERAGE);
gfx->SetAntialiasMode(AntialiasMode::SUBPIXEL);
break;
}

View File

@ -339,6 +339,12 @@ nsSVGUtils::UserSpace(nsIFrame *aNonSVGContext, const nsSVGLength2 *aLength)
return aLength->GetAnimValue(aNonSVGContext);
}
float
nsSVGUtils::UserSpace(const UserSpaceMetrics& aMetrics, const nsSVGLength2 *aLength)
{
return aLength->GetAnimValue(aMetrics);
}
nsSVGOuterSVGFrame *
nsSVGUtils::GetOuterSVGFrame(nsIFrame *aFrame)
{
@ -1017,23 +1023,43 @@ nsSVGUtils::FrameSpaceInCSSPxToUserSpaceOffset(nsIFrame *aFrame)
return gfxPoint();
}
static gfxRect
GetBoundingBoxRelativeRect(const nsSVGLength2 *aXYWH,
const gfxRect& aBBox)
{
return gfxRect(aBBox.x + nsSVGUtils::ObjectSpace(aBBox, &aXYWH[0]),
aBBox.y + nsSVGUtils::ObjectSpace(aBBox, &aXYWH[1]),
nsSVGUtils::ObjectSpace(aBBox, &aXYWH[2]),
nsSVGUtils::ObjectSpace(aBBox, &aXYWH[3]));
}
gfxRect
nsSVGUtils::GetRelativeRect(uint16_t aUnits, const nsSVGLength2 *aXYWH,
const gfxRect &aBBox, nsIFrame *aFrame)
const gfxRect& aBBox,
const UserSpaceMetrics& aMetrics)
{
float x, y, width, height;
if (aUnits == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
x = aBBox.X() + ObjectSpace(aBBox, &aXYWH[0]);
y = aBBox.Y() + ObjectSpace(aBBox, &aXYWH[1]);
width = ObjectSpace(aBBox, &aXYWH[2]);
height = ObjectSpace(aBBox, &aXYWH[3]);
} else {
x = UserSpace(aFrame, &aXYWH[0]);
y = UserSpace(aFrame, &aXYWH[1]);
width = UserSpace(aFrame, &aXYWH[2]);
height = UserSpace(aFrame, &aXYWH[3]);
return GetBoundingBoxRelativeRect(aXYWH, aBBox);
}
return gfxRect(x, y, width, height);
return gfxRect(UserSpace(aMetrics, &aXYWH[0]),
UserSpace(aMetrics, &aXYWH[1]),
UserSpace(aMetrics, &aXYWH[2]),
UserSpace(aMetrics, &aXYWH[3]));
}
gfxRect
nsSVGUtils::GetRelativeRect(uint16_t aUnits, const nsSVGLength2 *aXYWH,
const gfxRect& aBBox, nsIFrame *aFrame)
{
if (aUnits == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
return GetBoundingBoxRelativeRect(aXYWH, aBBox);
}
nsIContent* content = aFrame->GetContent();
if (content->IsSVG()) {
nsSVGElement* svgElement = static_cast<nsSVGElement*>(content);
return GetRelativeRect(aUnits, aXYWH, aBBox, SVGElementMetrics(svgElement));
}
return GetRelativeRect(aUnits, aXYWH, aBBox, NonSVGFrameUserSpaceMetrics(aFrame));
}
bool

View File

@ -58,6 +58,7 @@ class SVGAnimatedPreserveAspectRatio;
class SVGPreserveAspectRatio;
namespace dom {
class Element;
class UserSpaceMetrics;
} // namespace dom
namespace gfx {
class SourceSurface;
@ -274,12 +275,8 @@ public:
Input: length - length to be converted
*/
static float UserSpace(nsSVGElement *aSVGElement, const nsSVGLength2 *aLength);
/* Computes the input length in terms of user space coordinates.
Input: aFrame - object to be used for determining user space
length - length to be converted
*/
static float UserSpace(nsIFrame *aFrame, const nsSVGLength2 *aLength);
static float UserSpace(const mozilla::dom::UserSpaceMetrics& aMetrics, const nsSVGLength2 *aLength);
/* Find the outermost SVG frame of the passed frame */
static nsSVGOuterSVGFrame *
@ -454,7 +451,12 @@ public:
*/
static gfxRect
GetRelativeRect(uint16_t aUnits, const nsSVGLength2 *aXYWH,
const gfxRect &aBBox, nsIFrame *aFrame);
const gfxRect& aBBox, nsIFrame *aFrame);
static gfxRect
GetRelativeRect(uint16_t aUnits, const nsSVGLength2 *aXYWH,
const gfxRect& aBBox,
const mozilla::dom::UserSpaceMetrics& aMetrics);
/**
* Find the first frame, starting with aStartFrame and going up its

View File

@ -383,10 +383,10 @@ pref("media.getusermedia.screensharing.enabled", true);
#endif
#ifdef RELEASE_BUILD
pref("media.getusermedia.screensharing.allowed_domains", "");
pref("media.getusermedia.screensharing.allowed_domains", "webex.com,*.webex.com,collaborate.com,*.collaborate.com");
#else
// temporary value, not intended for release - bug 1049087
pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io");
pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io,webex.com,*.webex.com,collaborate.com,*.collaborate.com");
#endif
// OS/X 10.6 and XP have screen/window sharing off by default due to various issues - Caveat emptor
pref("media.getusermedia.screensharing.allow_on_old_platforms", false);

View File

@ -75,9 +75,7 @@ class MOZ_STACK_CLASS nsHtml5OtherDocUpdate {
};
nsHtml5TreeOperation::nsHtml5TreeOperation()
#ifdef DEBUG
: mOpCode(eTreeOpUninitialized)
#endif
{
MOZ_COUNT_CTOR(nsHtml5TreeOperation);
}
@ -960,7 +958,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
return rv;
}
default: {
NS_NOTREACHED("Bogus tree op");
MOZ_CRASH("Bogus tree op");
}
}
return NS_OK; // keep compiler happy

View File

@ -16,9 +16,7 @@ class nsHtml5StateSnapshot;
class nsHtml5DocumentBuilder;
enum eHtml5TreeOperation {
#ifdef DEBUG
eTreeOpUninitialized,
#endif
// main HTML5 ops
eTreeOpAppend,
eTreeOpDetach,

View File

@ -1092,4 +1092,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1418960624394000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1419283679619000);

View File

@ -34,6 +34,7 @@ crbug.com: did not receive HSTS header
crowdcurity.com: did not receive HSTS header
crypto.is: did not receive HSTS header
csawctf.poly.edu: did not receive HSTS header
dillonkorman.com: did not receive HSTS header
discovery.lookout.com: did not receive HSTS header
dl.google.com: did not receive HSTS header (error ignored - included regardless)
docs.google.com: did not receive HSTS header (error ignored - included regardless)
@ -67,12 +68,11 @@ hoerbuecher-und-hoerspiele.de: did not receive HSTS header
honeytracks.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no]
hostedtalkgadget.google.com: did not receive HSTS header (error ignored - included regardless)
howrandom.org: could not connect to host
ihrlotto.de: could not connect to host
in.xero.com: max-age too low: 3600
intercom.io: did not receive HSTS header
iop.intuit.com: max-age too low: 86400
irccloud.com: did not receive HSTS header
jitsi.org: did not receive HSTS header
jonaswitmer.ch: could not connect to host
jottit.com: could not connect to host
keymaster.lookout.com: did not receive HSTS header
kiwiirc.com: max-age too low: 5256000
@ -112,12 +112,12 @@ prodpad.com: did not receive HSTS header
profiles.google.com: did not receive HSTS header (error ignored - included regardless)
promecon-gmbh.de: did not receive HSTS header
rapidresearch.me: could not connect to host
rippleunion.com: did not receive HSTS header
riseup.net: did not receive HSTS header
sah3.net: could not connect to host
saturngames.co.uk: did not receive HSTS header
script.google.com: did not receive HSTS header (error ignored - included regardless)
security.google.com: did not receive HSTS header (error ignored - included regardless)
securityheaders.com: did not receive HSTS header
semenkovich.com: did not receive HSTS header
serverdensity.io: did not receive HSTS header
shops.neonisi.com: could not connect to host
@ -134,6 +134,7 @@ square.com: did not receive HSTS header
ssl.google-analytics.com: did not receive HSTS header (error ignored - included regardless)
ssl.panoramio.com: did not receive HSTS header
stocktrade.de: could not connect to host
strongest-privacy.com: could not connect to host
sunshinepress.org: could not connect to host
surfeasy.com: did not receive HSTS header
talk.google.com: did not receive HSTS header (error ignored - included regardless)
@ -143,8 +144,7 @@ translate.googleapis.com: did not receive HSTS header (error ignored - included
uprotect.it: could not connect to host
wallet.google.com: did not receive HSTS header (error ignored - included regardless)
webmail.mayfirst.org: did not receive HSTS header
wf-training-master.appspot.com: could not connect to host
wf-training-master.appspot.com: could not connect to host (error ignored - included regardless)
wf-training-master.appspot.com: did not receive HSTS header (error ignored - included regardless)
whonix.org: did not receive HSTS header
www.calyxinstitute.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no]
www.cueup.com: could not connect to host

View File

@ -8,7 +8,7 @@
/*****************************************************************************/
#include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1421379819168000);
const PRTime gPreloadListExpirationTime = INT64_C(1421702876088000);
class nsSTSPreload
{
@ -122,7 +122,6 @@ static const nsSTSPreload kSTSPreloadList[] = {
{ "detectify.com", false },
{ "developer.mydigipass.com", false },
{ "die-besten-weisheiten.de", true },
{ "dillonkorman.com", true },
{ "dist.torproject.org", false },
{ "dl.google.com", true },
{ "dm.lookout.com", false },
@ -216,6 +215,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
{ "jelmer.co.uk", true },
{ "jelmer.uk", true },
{ "jfreitag.de", true },
{ "jitsi.org", false },
{ "jonas-keidel.de", true },
{ "jonaswitmer.ch", true },
{ "julian-kipka.de", true },
@ -351,7 +351,6 @@ static const nsSTSPreload kSTSPreloadList[] = {
{ "reviews.anime.my", true },
{ "riccy.org", true },
{ "riesenmagnete.de", true },
{ "rippleunion.com", true },
{ "rme.li", false },
{ "robteix.com", true },
{ "roddis.net", false },
@ -370,6 +369,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
{ "sdsl-speedtest.de", true },
{ "security-carpet.com", true },
{ "security.google.com", true },
{ "securityheaders.com", true },
{ "secuvera.de", true },
{ "seifried.org", true },
{ "servethecity-karlsruhe.de", true },

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