зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team a=merge
This commit is contained in:
Коммит
9b3e22a50e
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "b0a272695ccf247884000f785ed4cbfe49ae4141",
|
||||
"revision": "123eb4378d299e61d73be5e290f7d9ca00f2fb41",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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":
|
||||
|
|
|
@ -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":
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -13,6 +13,9 @@ BEGIN_WORKERS_NAMESPACE
|
|||
JSPrincipals*
|
||||
GetWorkerPrincipal();
|
||||
|
||||
void
|
||||
DestroyWorkerPrincipals(JSPrincipals* aPrincipals);
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
#endif /* mozilla_dom_workers_principal_h__ */
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -24,6 +24,8 @@ struct JSPrincipals {
|
|||
uint32_t debugToken;
|
||||
#endif
|
||||
|
||||
JSPrincipals() : refcount(0) {}
|
||||
|
||||
void setDebugToken(uint32_t token) {
|
||||
# ifdef JS_DEBUG
|
||||
debugToken = token;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -546,6 +546,9 @@ class GCRuntime
|
|||
void checkForCompartmentMismatches();
|
||||
#endif
|
||||
|
||||
void callFinalizeCallbacks(FreeOp *fop, JSFinalizeStatus status) const;
|
||||
void callMovingGCCallbacks() const;
|
||||
|
||||
public:
|
||||
JSRuntime *rt;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 = ®S.sp[-2].toObject();
|
||||
bool cond;
|
||||
if (!js_IteratorMore(cx, obj, &cond))
|
||||
if (!IteratorMore(cx, obj, &cond))
|
||||
goto error;
|
||||
REGS.sp[-1].setBoolean(cond);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = "漢字";
|
|||
var HiraganaChars = "ひらがな";
|
||||
var KatakanaChars = "カタカナ";
|
||||
var JapaneseFullStop = "。";
|
||||
var JapaneseComma = "、";
|
||||
var JapaneseComma = "、";
|
||||
var ModifierColon = "꞉";
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,9 +16,7 @@ class nsHtml5StateSnapshot;
|
|||
class nsHtml5DocumentBuilder;
|
||||
|
||||
enum eHtml5TreeOperation {
|
||||
#ifdef DEBUG
|
||||
eTreeOpUninitialized,
|
||||
#endif
|
||||
// main HTML5 ops
|
||||
eTreeOpAppend,
|
||||
eTreeOpDetach,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 },
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче