mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central and inbound
This commit is contained in:
commit
0c010bd02f
@ -44,15 +44,19 @@ var checkTestResults = function() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function loadElements() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_evalscript_main_getCRMFRequest.html';
|
||||
document.getElementById('cspframe2').src = 'file_CSP_evalscript_main_allowed_getCRMFRequest.html';
|
||||
document.getElementById('cspframe3').src = 'file_CSP_evalscript_no_CSP_at_all.html';
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// set up and go
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_evalscript_main_getCRMFRequest.html';
|
||||
document.getElementById('cspframe2').src = 'file_CSP_evalscript_main_allowed_getCRMFRequest.html';
|
||||
document.getElementById('cspframe3').src = 'file_CSP_evalscript_no_CSP_at_all.html';
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.unsafe_legacy_crypto.enabled", true]]},
|
||||
loadElements);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
41
dom/events/test/bug1017086_inner.html
Normal file
41
dom/events/test/bug1017086_inner.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1017086
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1017086</title>
|
||||
<meta name="author" content="Maksim Lebedev" />
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
/** Test for Bug 1017086 **/
|
||||
var testelem = undefined;
|
||||
var pointer_events = ["onpointerover", "onpointerenter",
|
||||
"onpointermove",
|
||||
"onpointerdown", "onpointerup",
|
||||
"onpointerout", "onpointerleave",
|
||||
"onpointercancel"];
|
||||
function check(expected_value, event_name, container, container_name) {
|
||||
var text = event_name + " in " + container_name + " should be " + expected_value;
|
||||
parent.is(event_name in container, expected_value, text);
|
||||
}
|
||||
function runTest() {
|
||||
testelem = document.getElementById("test");
|
||||
is(!!testelem, true, "Document should have element with id 'test'");
|
||||
parent.turnOnOffPointerEvents( function() {
|
||||
parent.part_of_checks(pointer_events, check, window, document, testelem);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="runTest();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1017086">Mozilla Bug 1017086</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -126,11 +126,17 @@ skip-if = toolkit == 'android'
|
||||
[test_bug864040.html]
|
||||
skip-if = buildapp == 'b2g' # b2g(failing when the test gets moved around, and on debug) b2g-debug(failing when the test gets moved around, and on debug) b2g-desktop(failing when the test gets moved around, and on debug)
|
||||
[test_bug930374-content.html]
|
||||
[test_bug944011.html]
|
||||
[test_bug944847.html]
|
||||
[test_bug946632.html]
|
||||
[test_bug967796.html]
|
||||
skip-if = toolkit == "gonk" || e10s
|
||||
[test_bug944011.html]
|
||||
[test_bug946632.html]
|
||||
[test_bug985988.html]
|
||||
[test_bug998809.html]
|
||||
[test_bug1017086_disable.html]
|
||||
support-files = bug1017086_inner.html
|
||||
[test_bug1017086_enable.html]
|
||||
support-files = bug1017086_inner.html
|
||||
[test_clickevent_on_input.html]
|
||||
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
|
||||
[test_continuous_wheel_events.html]
|
||||
@ -140,6 +146,7 @@ skip-if = buildapp == 'b2g' || e10s # b2g(5535 passed, 108 failed - more tests r
|
||||
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
|
||||
[test_dom_mouse_event.html]
|
||||
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
|
||||
[test_dom_storage_event.html]
|
||||
[test_dom_wheel_event.html]
|
||||
skip-if = buildapp == 'b2g' || e10s # b2g(456 failed out of 19873, mousewheel test) b2g-debug(456 failed out of 19873, mousewheel test) b2g-desktop(456 failed out of 19873, mousewheel test)
|
||||
[test_draggableprop.html]
|
||||
@ -159,6 +166,3 @@ skip-if = buildapp == 'mulet'
|
||||
[test_onerror_handler_args.html]
|
||||
[test_wheel_default_action.html]
|
||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || e10s
|
||||
[test_bug985988.html]
|
||||
[test_dom_storage_event.html]
|
||||
[test_bug998809.html]
|
||||
|
41
dom/events/test/test_bug1017086_disable.html
Normal file
41
dom/events/test/test_bug1017086_disable.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1017086
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1017086</title>
|
||||
<meta name="author" content="Maksim Lebedev" />
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="text/javascript">
|
||||
/** Test for Bug 1017086 **/
|
||||
var pointer_events_enabled = false;
|
||||
function prepareTest() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
turnOnOffPointerEvents(startTest);
|
||||
}
|
||||
function turnOnOffPointerEvents(callback) {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["dom.w3c_pointer_events.enabled", pointer_events_enabled]
|
||||
]
|
||||
}, callback);
|
||||
}
|
||||
function startTest() {
|
||||
var iframe = document.getElementById("testFrame");
|
||||
iframe.src = "bug1017086_inner.html";
|
||||
}
|
||||
function part_of_checks(pointer_events, check, window, document, testelem) {
|
||||
for(item in pointer_events) { check(false, pointer_events[item], window, "window"); }
|
||||
for(item in pointer_events) { check(false, pointer_events[item], document, "document"); }
|
||||
for(item in pointer_events) { check(false, pointer_events[item], testelem, "element"); }
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="prepareTest()">
|
||||
<iframe id="testFrame" height="700" width="700"></iframe>
|
||||
</body>
|
||||
</html>
|
43
dom/events/test/test_bug1017086_enable.html
Normal file
43
dom/events/test/test_bug1017086_enable.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1017086
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1017086</title>
|
||||
<meta name="author" content="Maksim Lebedev" />
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="text/javascript">
|
||||
/** Test for Bug 1017086 **/
|
||||
var pointer_events_enabled = true;
|
||||
function prepareTest() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
turnOnOffPointerEvents(startTest);
|
||||
}
|
||||
function turnOnOffPointerEvents(callback) {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["dom.w3c_pointer_events.enabled", pointer_events_enabled]
|
||||
]
|
||||
}, callback);
|
||||
}
|
||||
function startTest() {
|
||||
var iframe = document.getElementById("testFrame");
|
||||
iframe.src = "bug1017086_inner.html";
|
||||
}
|
||||
function part_of_checks(pointer_events, check, window, document, testelem) {
|
||||
for(item in pointer_events) { check(true, pointer_events[item], window, "window"); }
|
||||
/** TODO
|
||||
for(item in pointer_events) { check(false, pointer_events[item], document, "document"); }
|
||||
**/
|
||||
for(item in pointer_events) { check(true, pointer_events[item], testelem, "element"); }
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="prepareTest()">
|
||||
<iframe id="testFrame" height="700" width="700"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -1650,8 +1650,8 @@ ContentChild::RecvActivateA11y()
|
||||
#ifdef ACCESSIBILITY
|
||||
// Start accessibility in content process if it's running in chrome
|
||||
// process.
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
do_GetService("@mozilla.org/accessibilityService;1");
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
services::GetAccessibilityService();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -1,2 +0,0 @@
|
||||
[test_no_legacy.html]
|
||||
skip-if = e10s
|
@ -2,3 +2,4 @@
|
||||
skip-if = e10s
|
||||
|
||||
[test_getRandomValues.html]
|
||||
[test_no_legacy.html]
|
||||
|
@ -2,50 +2,59 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Test presence of legacy window.crypto features when
|
||||
MOZ_DISABLE_CRYPTOLEGACY is NOT set.</title>
|
||||
MOZ_DISABLE_CRYPTOLEGACY is NOT set and dom.unsafe_legacy_crypto.enabled is true</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
ok("crypto" in window, "crypto in window");
|
||||
ok("version" in window.crypto, "version in window.crypto");
|
||||
ok("enableSmartCardEvents" in window.crypto,
|
||||
"enableSmartCardEvents in window.crypto");
|
||||
ok("generateCRMFRequest" in window.crypto,
|
||||
"generateCRMFRequest in window.crypto");
|
||||
ok("importUserCertificates" in window.crypto,
|
||||
"importUserCertificates in window.crypto");
|
||||
ok("signText" in window.crypto, "signText in window.crypto");
|
||||
function test_unsafe_legacy_crypto_enabled() {
|
||||
ok("crypto" in window, "crypto in window");
|
||||
ok("version" in window.crypto, "version in window.crypto");
|
||||
ok("enableSmartCardEvents" in window.crypto,
|
||||
"enableSmartCardEvents in window.crypto");
|
||||
ok("generateCRMFRequest" in window.crypto,
|
||||
"generateCRMFRequest in window.crypto");
|
||||
ok("importUserCertificates" in window.crypto,
|
||||
"importUserCertificates in window.crypto");
|
||||
ok("signText" in window.crypto, "signText in window.crypto");
|
||||
|
||||
function jsCallback () {
|
||||
function jsCallback () {
|
||||
}
|
||||
|
||||
try {
|
||||
window.crypto.generateCRMFRequest(null, null, null, null, jsCallback.toString());
|
||||
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
|
||||
} catch (e) {
|
||||
ok(e.toString().search(/Failure/) > -1,
|
||||
"Expected error: ReqDN cannot be null");
|
||||
}
|
||||
|
||||
try {
|
||||
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
|
||||
null);
|
||||
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
|
||||
} catch (e) {
|
||||
ok(e.toString().search(/Failure/) > -1,
|
||||
"Expected error: jsCallback cannot be null");
|
||||
}
|
||||
|
||||
try {
|
||||
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
|
||||
jsCallback.toString(), 1024);
|
||||
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
|
||||
} catch (e) {
|
||||
ok(e.toString().search(/TypeError/) > -1,
|
||||
"Expected error: Not enough arguments");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
try {
|
||||
window.crypto.generateCRMFRequest(null, null, null, null, jsCallback.toString());
|
||||
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
|
||||
} catch (e) {
|
||||
ok(e.toString().search(/Failure/) > -1,
|
||||
"Expected error: ReqDN cannot be null");
|
||||
}
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.unsafe_legacy_crypto.enabled", true]]},
|
||||
test_unsafe_legacy_crypto_enabled);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
try {
|
||||
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
|
||||
null);
|
||||
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
|
||||
} catch (e) {
|
||||
ok(e.toString().search(/Failure/) > -1,
|
||||
"Expected error: jsCallback cannot be null");
|
||||
}
|
||||
|
||||
try {
|
||||
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
|
||||
jsCallback.toString(), 1024);
|
||||
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
|
||||
} catch (e) {
|
||||
ok(e.toString().search(/TypeError/) > -1,
|
||||
"Expected error: Not enough arguments");
|
||||
}
|
||||
</script>
|
||||
</body></html>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Test lack of legacy window.crypto features when
|
||||
MOZ_DISABLE_CRYPTOLEGACY is set</title>
|
||||
MOZ_DISABLE_CRYPTOLEGACY is set or dom.unsafe_legacy_crypto.enabled is false</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
|
@ -48,11 +48,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gtk2':
|
||||
'mochitest/pointerlock/mochitest.ini',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_DISABLE_CRYPTOLEGACY']:
|
||||
MOCHITEST_MANIFESTS += [
|
||||
'mochitest/crypto/mochitest-no-legacy.ini',
|
||||
]
|
||||
else:
|
||||
if not CONFIG['MOZ_DISABLE_CRYPTOLEGACY']:
|
||||
MOCHITEST_MANIFESTS += [
|
||||
'mochitest/crypto/mochitest-legacy.ini',
|
||||
]
|
||||
|
@ -23,12 +23,13 @@ interface Crypto {
|
||||
#ifndef MOZ_DISABLE_CRYPTOLEGACY
|
||||
[NoInterfaceObject]
|
||||
interface CryptoLegacy {
|
||||
[Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
readonly attribute DOMString version;
|
||||
|
||||
[SetterThrows]
|
||||
[SetterThrows,Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
attribute boolean enableSmartCardEvents;
|
||||
|
||||
[Throws,NewObject]
|
||||
[Throws,NewObject,Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
CRMFObject? generateCRMFRequest(ByteString? reqDN,
|
||||
ByteString? regToken,
|
||||
ByteString? authenticator,
|
||||
@ -36,16 +37,17 @@ interface CryptoLegacy {
|
||||
ByteString? jsCallback,
|
||||
any... args);
|
||||
|
||||
[Throws]
|
||||
[Throws,Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
DOMString importUserCertificates(DOMString nickname,
|
||||
DOMString cmmfResponse,
|
||||
boolean doForcedBackup);
|
||||
|
||||
[Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
DOMString signText(DOMString stringToSign,
|
||||
DOMString caOption,
|
||||
ByteString... args);
|
||||
|
||||
[Throws]
|
||||
[Throws,Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
void logout();
|
||||
};
|
||||
|
||||
|
@ -653,7 +653,9 @@ DrawGradient(CGColorSpaceRef aColorSpace,
|
||||
if (aPattern.GetType() == PatternType::LINEAR_GRADIENT) {
|
||||
const LinearGradientPattern& pat = static_cast<const LinearGradientPattern&>(aPattern);
|
||||
GradientStopsCG *stops = static_cast<GradientStopsCG*>(pat.mStops.get());
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(pat.mMatrix));
|
||||
CGAffineTransform patternMatrix = GfxMatrixToCGAffineTransform(pat.mMatrix);
|
||||
CGContextConcatCTM(cg, patternMatrix);
|
||||
CGRect extents = CGRectApplyAffineTransform(aExtents, CGAffineTransformInvert(patternMatrix));
|
||||
if (stops->mExtend == ExtendMode::CLAMP) {
|
||||
|
||||
// XXX: we should take the m out of the properties of LinearGradientPatterns
|
||||
@ -667,11 +669,13 @@ DrawGradient(CGColorSpaceRef aColorSpace,
|
||||
CGContextDrawLinearGradient(cg, stops->mGradient, startPoint, endPoint,
|
||||
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
|
||||
} else if (stops->mExtend == ExtendMode::REPEAT || stops->mExtend == ExtendMode::REFLECT) {
|
||||
DrawLinearRepeatingGradient(aColorSpace, cg, pat, aExtents, stops->mExtend == ExtendMode::REFLECT);
|
||||
DrawLinearRepeatingGradient(aColorSpace, cg, pat, extents, stops->mExtend == ExtendMode::REFLECT);
|
||||
}
|
||||
} else if (aPattern.GetType() == PatternType::RADIAL_GRADIENT) {
|
||||
const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(pat.mMatrix));
|
||||
CGAffineTransform patternMatrix = GfxMatrixToCGAffineTransform(pat.mMatrix);
|
||||
CGContextConcatCTM(cg, patternMatrix);
|
||||
CGRect extents = CGRectApplyAffineTransform(aExtents, CGAffineTransformInvert(patternMatrix));
|
||||
GradientStopsCG *stops = static_cast<GradientStopsCG*>(pat.mStops.get());
|
||||
if (stops->mExtend == ExtendMode::CLAMP) {
|
||||
|
||||
@ -685,7 +689,7 @@ DrawGradient(CGColorSpaceRef aColorSpace,
|
||||
CGContextDrawRadialGradient(cg, stops->mGradient, startCenter, startRadius, endCenter, endRadius,
|
||||
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
|
||||
} else if (stops->mExtend == ExtendMode::REPEAT || stops->mExtend == ExtendMode::REFLECT) {
|
||||
DrawRadialRepeatingGradient(aColorSpace, cg, pat, aExtents, stops->mExtend == ExtendMode::REFLECT);
|
||||
DrawRadialRepeatingGradient(aColorSpace, cg, pat, extents, stops->mExtend == ExtendMode::REFLECT);
|
||||
}
|
||||
} else {
|
||||
assert(0);
|
||||
|
@ -530,6 +530,10 @@ ContainerRender(ContainerT* aContainer,
|
||||
LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(aContainer->GetMaskLayer(),
|
||||
effectChain,
|
||||
!aContainer->GetTransform().CanDraw2D());
|
||||
if (autoMaskEffect.Failed()) {
|
||||
NS_WARNING("Failed to apply a mask effect.");
|
||||
return;
|
||||
}
|
||||
|
||||
aContainer->AddBlendModeEffect(effectChain);
|
||||
effectChain.mPrimaryEffect = new EffectRenderTarget(surface);
|
||||
|
@ -828,7 +828,7 @@ LayerManagerComposite::CreateRefLayerComposite()
|
||||
LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
|
||||
EffectChain& aEffects,
|
||||
bool aIs3D)
|
||||
: mCompositable(nullptr)
|
||||
: mCompositable(nullptr), mFailed(false)
|
||||
{
|
||||
if (!aMaskLayer) {
|
||||
return;
|
||||
@ -837,11 +837,13 @@ LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
|
||||
mCompositable = ToLayerComposite(aMaskLayer)->GetCompositableHost();
|
||||
if (!mCompositable) {
|
||||
NS_WARNING("Mask layer with no compositable host");
|
||||
mFailed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mCompositable->AddMaskEffect(aEffects, aMaskLayer->GetEffectiveTransform(), aIs3D)) {
|
||||
mCompositable = nullptr;
|
||||
mFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,8 +184,10 @@ public:
|
||||
bool aIs3D = false);
|
||||
~AutoAddMaskEffect();
|
||||
|
||||
bool Failed() const { return mFailed; }
|
||||
private:
|
||||
CompositableHost* mCompositable;
|
||||
bool mFailed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -21,3 +21,20 @@ keeping them separate from other `Debugger` facilities.
|
||||
You can retrieve the allocation site for a given object with the
|
||||
[`Debugger.Object.prototype.allocationSite`][allocation-site] accessor
|
||||
property.
|
||||
|
||||
`maxAllocationsLogLength`
|
||||
: The maximum number of allocation sites to accumulate in the allocations log
|
||||
at a time. Its default value is `5000`.
|
||||
|
||||
## Function Properties of the `Debugger.Memory.prototype` Object
|
||||
|
||||
`drainAllocationsLog()`
|
||||
: When `trackingAllocationSites` is `true`, this method returns an array of
|
||||
allocation sites (as [captured stacks][saved-frame]) for recent `Object`
|
||||
allocations within the set of debuggees. *Recent* is defined as the
|
||||
`maxAllocationsLogLength` most recent `Object` allocations since the last
|
||||
call to `drainAllocationsLog`. Therefore, calling this method effectively
|
||||
clears the log.
|
||||
|
||||
When `trackingAllocationSites` is `false`, `drainAllocationsLog()` throws an
|
||||
`Error`.
|
||||
|
31
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-01.js
Normal file
31
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-01.js
Normal file
@ -0,0 +1,31 @@
|
||||
// Test basic usage of drainAllocationsLog()
|
||||
|
||||
const root = newGlobal();
|
||||
const dbg = new Debugger();
|
||||
const wrappedRoot = dbg.addDebuggee(root)
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
|
||||
root.eval("(" + function immediate() {
|
||||
this.tests = [
|
||||
({}),
|
||||
[],
|
||||
/(two|2)\s*problems/,
|
||||
new function Ctor(){},
|
||||
new Object(),
|
||||
new Array(),
|
||||
new Date(),
|
||||
];
|
||||
} + "());");
|
||||
|
||||
const allocs = dbg.memory.drainAllocationsLog();
|
||||
print(allocs.join("\n--------------------------------------------------------------------------\n"));
|
||||
print("Total number of allocations logged: " + allocs.length);
|
||||
|
||||
let idx = -1;
|
||||
for (let object of root.tests) {
|
||||
let wrappedObject = wrappedRoot.makeDebuggeeValue(object);
|
||||
let allocSite = wrappedObject.allocationSite;
|
||||
let newIdx = allocs.indexOf(allocSite);
|
||||
assertEq(newIdx > idx, true);
|
||||
idx = newIdx;
|
||||
}
|
14
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-02.js
Normal file
14
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-02.js
Normal file
@ -0,0 +1,14 @@
|
||||
// Test that drainAllocationsLog fails when we aren't trackingAllocationSites.
|
||||
|
||||
load(libdir + 'asserts.js');
|
||||
|
||||
const root = newGlobal();
|
||||
const dbg = new Debugger();
|
||||
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
root.eval("this.alloc1 = {}");
|
||||
dbg.memory.trackingAllocationSites = false;
|
||||
root.eval("this.alloc2 = {};");
|
||||
|
||||
assertThrowsInstanceOf(() => dbg.memory.drainAllocationsLog(),
|
||||
Error);
|
24
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-03.js
Normal file
24
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-03.js
Normal file
@ -0,0 +1,24 @@
|
||||
// Test when there are more allocations than the maximum log length.
|
||||
|
||||
const root = newGlobal();
|
||||
const dbg = new Debugger();
|
||||
dbg.addDebuggee(root)
|
||||
|
||||
dbg.memory.maxAllocationsLogLength = 3;
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
|
||||
root.eval([
|
||||
"this.alloc1 = {};", // line 1
|
||||
"this.alloc2 = {};", // line 2
|
||||
"this.alloc3 = {};", // line 3
|
||||
"this.alloc4 = {};", // line 4
|
||||
].join("\n"));
|
||||
|
||||
const allocs = dbg.memory.drainAllocationsLog();
|
||||
|
||||
// Should have stayed at the maximum length.
|
||||
assertEq(allocs.length, 3);
|
||||
// Should have kept the most recent allocation.
|
||||
assertEq(allocs[2].line, 4);
|
||||
// Should have thrown away the oldest allocation.
|
||||
assertEq(allocs.map(x => x.line).indexOf(1), -1);
|
21
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-04.js
Normal file
21
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-04.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Test that when we shorten the maximum log length, we won't get a longer log
|
||||
// than that new maximum afterwards.
|
||||
|
||||
const root = newGlobal();
|
||||
const dbg = new Debugger();
|
||||
dbg.addDebuggee(root)
|
||||
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
|
||||
root.eval([
|
||||
"this.alloc1 = {};", // line 1
|
||||
"this.alloc2 = {};", // line 2
|
||||
"this.alloc3 = {};", // line 3
|
||||
"this.alloc4 = {};", // line 4
|
||||
].join("\n"));
|
||||
|
||||
dbg.memory.maxAllocationsLogLength = 1;
|
||||
const allocs = dbg.memory.drainAllocationsLog();
|
||||
|
||||
// Should have trimmed down to the new maximum length.
|
||||
assertEq(allocs.length, 1);
|
@ -0,0 +1,9 @@
|
||||
// Test an empty allocation log.
|
||||
|
||||
const root = newGlobal();
|
||||
const dbg = new Debugger();
|
||||
dbg.addDebuggee(root)
|
||||
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
const allocs = dbg.memory.drainAllocationsLog();
|
||||
assertEq(allocs.length, 0);
|
23
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-06.js
Normal file
23
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-06.js
Normal file
@ -0,0 +1,23 @@
|
||||
// Test doing a GC while we have a non-empty log.
|
||||
|
||||
const root = newGlobal();
|
||||
const dbg = new Debugger();
|
||||
dbg.addDebuggee(root)
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
|
||||
root.eval("(" + function immediate() {
|
||||
this.tests = [
|
||||
({}),
|
||||
[],
|
||||
/(two|2)\s*problems/,
|
||||
new function Ctor(){},
|
||||
new Object(),
|
||||
new Array(),
|
||||
new Date(),
|
||||
];
|
||||
} + "());");
|
||||
|
||||
gc();
|
||||
|
||||
const allocs = dbg.memory.drainAllocationsLog();
|
||||
assertEq(allocs.length >= root.tests.length, true);
|
10
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-07.js
Normal file
10
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-07.js
Normal file
@ -0,0 +1,10 @@
|
||||
// Test retrieving the log when allocation tracking hasn't ever been enabled.
|
||||
|
||||
load(libdir + 'asserts.js');
|
||||
|
||||
const root = newGlobal();
|
||||
const dbg = new Debugger();
|
||||
dbg.addDebuggee(root)
|
||||
|
||||
assertThrowsInstanceOf(() => dbg.memory.drainAllocationsLog(),
|
||||
Error);
|
30
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-08.js
Normal file
30
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-08.js
Normal file
@ -0,0 +1,30 @@
|
||||
// Test retrieving the log multiple times.
|
||||
|
||||
const root = newGlobal();
|
||||
const dbg = new Debugger();
|
||||
dbg.addDebuggee(root)
|
||||
|
||||
root.eval([
|
||||
"this.allocs = [];",
|
||||
"this.doFirstAlloc = " + function () {
|
||||
this.allocs.push({}); this.firstAllocLine = Error().lineNumber;
|
||||
},
|
||||
"this.doSecondAlloc = " + function () {
|
||||
this.allocs.push(new Object()); this.secondAllocLine = Error().lineNumber;
|
||||
}
|
||||
].join("\n"));
|
||||
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
|
||||
root.doFirstAlloc();
|
||||
let allocs1 = dbg.memory.drainAllocationsLog();
|
||||
root.doSecondAlloc();
|
||||
let allocs2 = dbg.memory.drainAllocationsLog();
|
||||
|
||||
let allocs1Lines = allocs1.map(x => x.line);
|
||||
assertEq(allocs1Lines.indexOf(root.firstAllocLine) != -1, true);
|
||||
assertEq(allocs1Lines.indexOf(root.secondAllocLine) == -1, true);
|
||||
|
||||
let allocs2Lines = allocs2.map(x => x.line);
|
||||
assertEq(allocs2Lines.indexOf(root.secondAllocLine) != -1, true);
|
||||
assertEq(allocs2Lines.indexOf(root.firstAllocLine) == -1, true);
|
20
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-09.js
Normal file
20
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-09.js
Normal file
@ -0,0 +1,20 @@
|
||||
// Test logs that contain allocations from many debuggee compartments.
|
||||
|
||||
const dbg = new Debugger();
|
||||
|
||||
const root1 = newGlobal();
|
||||
const root2 = newGlobal();
|
||||
const root3 = newGlobal();
|
||||
|
||||
dbg.addDebuggee(root1);
|
||||
dbg.addDebuggee(root2);
|
||||
dbg.addDebuggee(root3);
|
||||
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
|
||||
root1.eval("this.alloc = {}");
|
||||
root2.eval("this.alloc = {}");
|
||||
root3.eval("this.alloc = {}");
|
||||
|
||||
const allocs = dbg.memory.drainAllocationsLog();
|
||||
assertEq(allocs.length >= 3, true);
|
21
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-10.js
Normal file
21
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-10.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Test logs that contain allocations from debuggee compartments added as we are
|
||||
// logging.
|
||||
|
||||
const dbg = new Debugger();
|
||||
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
|
||||
const root1 = newGlobal();
|
||||
dbg.addDebuggee(root1);
|
||||
root1.eval("this.alloc = {}");
|
||||
|
||||
const root2 = newGlobal();
|
||||
dbg.addDebuggee(root2);
|
||||
root2.eval("this.alloc = {}");
|
||||
|
||||
const root3 = newGlobal();
|
||||
dbg.addDebuggee(root3);
|
||||
root3.eval("this.alloc = {}");
|
||||
|
||||
const allocs = dbg.memory.drainAllocationsLog();
|
||||
assertEq(allocs.length >= 3, true);
|
25
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-11.js
Normal file
25
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-11.js
Normal file
@ -0,0 +1,25 @@
|
||||
// Test logs that shouldn't contain allocations from debuggee compartments
|
||||
// removed as we are logging.
|
||||
|
||||
const dbg = new Debugger();
|
||||
|
||||
const root1 = newGlobal();
|
||||
dbg.addDebuggee(root1);
|
||||
const root2 = newGlobal();
|
||||
dbg.addDebuggee(root2);
|
||||
const root3 = newGlobal();
|
||||
dbg.addDebuggee(root3);
|
||||
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
|
||||
dbg.removeDebuggee(root1);
|
||||
root1.eval("this.alloc = {}");
|
||||
|
||||
dbg.removeDebuggee(root2);
|
||||
root2.eval("this.alloc = {}");
|
||||
|
||||
dbg.removeDebuggee(root3);
|
||||
root3.eval("this.alloc = {}");
|
||||
|
||||
const allocs = dbg.memory.drainAllocationsLog();
|
||||
assertEq(allocs.length, 0);
|
17
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-12.js
Normal file
17
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-12.js
Normal file
@ -0,0 +1,17 @@
|
||||
// Test that disabling the debugger disables allocation tracking.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
const dbg = new Debugger();
|
||||
const root = newGlobal();
|
||||
dbg.addDebuggee(root);
|
||||
|
||||
dbg.memory.trackingAllocationSites = true;
|
||||
dbg.enabled = false;
|
||||
|
||||
root.eval("this.alloc = {}");
|
||||
|
||||
// We shouldn't accumulate allocations in our log while the debugger is
|
||||
// disabled.
|
||||
let allocs = dbg.memory.drainAllocationsLog();
|
||||
assertEq(allocs.length, 0);
|
18
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-13.js
Normal file
18
js/src/jit-test/tests/debug/Memory-drainAllocationsLog-13.js
Normal file
@ -0,0 +1,18 @@
|
||||
// Test that we don't crash while logging allocations and there is
|
||||
// off-main-thread compilation. OMT compilation will allocate functions and
|
||||
// regexps, but we just punt on measuring that accurately.
|
||||
|
||||
if (helperThreadCount() === 0) {
|
||||
quit(0);
|
||||
}
|
||||
|
||||
const root = newGlobal();
|
||||
root.eval("this.dbg = new Debugger()");
|
||||
root.dbg.addDebuggee(this);
|
||||
root.dbg.memory.trackingAllocationSites = true;
|
||||
|
||||
offThreadCompileScript(
|
||||
"function foo() {\n" +
|
||||
" print('hello world');\n" +
|
||||
"}"
|
||||
);
|
@ -2971,6 +2971,28 @@ MLoadFixedSlot::mightAlias(const MDefinition *store) const
|
||||
return true;
|
||||
}
|
||||
|
||||
MDefinition *
|
||||
MLoadFixedSlot::foldsTo(TempAllocator &alloc)
|
||||
{
|
||||
if (!dependency() || !dependency()->isStoreFixedSlot())
|
||||
return this;
|
||||
|
||||
MStoreFixedSlot *store = dependency()->toStoreFixedSlot();
|
||||
if (!store->block()->dominates(block()))
|
||||
return this;
|
||||
|
||||
if (store->object() != object())
|
||||
return this;
|
||||
|
||||
if (store->slot() != slot())
|
||||
return this;
|
||||
|
||||
if (store->value()->type() != type())
|
||||
return this;
|
||||
|
||||
return store->value();
|
||||
}
|
||||
|
||||
bool
|
||||
MAsmJSLoadHeap::mightAlias(const MDefinition *def) const
|
||||
{
|
||||
@ -3023,6 +3045,25 @@ MAsmJSLoadGlobalVar::congruentTo(const MDefinition *ins) const
|
||||
return false;
|
||||
}
|
||||
|
||||
MDefinition *
|
||||
MAsmJSLoadGlobalVar::foldsTo(TempAllocator &alloc)
|
||||
{
|
||||
if (!dependency() || !dependency()->isAsmJSStoreGlobalVar())
|
||||
return this;
|
||||
|
||||
MAsmJSStoreGlobalVar *store = dependency()->toAsmJSStoreGlobalVar();
|
||||
if (!store->block()->dominates(block()))
|
||||
return this;
|
||||
|
||||
if (store->globalDataOffset() != globalDataOffset())
|
||||
return this;
|
||||
|
||||
if (store->value()->type() != type())
|
||||
return this;
|
||||
|
||||
return store->value();
|
||||
}
|
||||
|
||||
HashNumber
|
||||
MAsmJSLoadFuncPtr::valueHash() const
|
||||
{
|
||||
@ -3075,6 +3116,47 @@ MLoadSlot::valueHash() const
|
||||
return hash;
|
||||
}
|
||||
|
||||
MDefinition *
|
||||
MLoadSlot::foldsTo(TempAllocator &alloc)
|
||||
{
|
||||
if (!dependency() || !dependency()->isStoreSlot())
|
||||
return this;
|
||||
|
||||
MStoreSlot *store = dependency()->toStoreSlot();
|
||||
if (!store->block()->dominates(block()))
|
||||
return this;
|
||||
|
||||
if (store->slots() != slots())
|
||||
return this;
|
||||
|
||||
if (store->value()->type() != type())
|
||||
return this;
|
||||
|
||||
return store->value();
|
||||
}
|
||||
|
||||
MDefinition *
|
||||
MLoadElement::foldsTo(TempAllocator &alloc)
|
||||
{
|
||||
if (!dependency() || !dependency()->isStoreElement())
|
||||
return this;
|
||||
|
||||
MStoreElement *store = dependency()->toStoreElement();
|
||||
if (!store->block()->dominates(block()))
|
||||
return this;
|
||||
|
||||
if (store->elements() != elements())
|
||||
return this;
|
||||
|
||||
if (store->index() != index())
|
||||
return this;
|
||||
|
||||
if (store->value()->type() != type())
|
||||
return this;
|
||||
|
||||
return store->value();
|
||||
}
|
||||
|
||||
bool
|
||||
MGuardShapePolymorphic::congruentTo(const MDefinition *ins) const
|
||||
{
|
||||
|
@ -6625,6 +6625,7 @@ class MLoadElement
|
||||
return false;
|
||||
return congruentIfOperandsEqual(other);
|
||||
}
|
||||
MDefinition *foldsTo(TempAllocator &alloc);
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::Element);
|
||||
}
|
||||
@ -7423,6 +7424,8 @@ class MLoadFixedSlot
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
|
||||
MDefinition *foldsTo(TempAllocator &alloc);
|
||||
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::FixedSlot);
|
||||
}
|
||||
@ -8314,6 +8317,9 @@ class MLoadSlot
|
||||
return false;
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
|
||||
MDefinition *foldsTo(TempAllocator &alloc);
|
||||
|
||||
AliasSet getAliasSet() const {
|
||||
JS_ASSERT(slots()->type() == MIRType_Slots);
|
||||
return AliasSet::Load(AliasSet::DynamicSlot);
|
||||
@ -10591,6 +10597,7 @@ class MAsmJSLoadGlobalVar : public MNullaryInstruction
|
||||
|
||||
HashNumber valueHash() const;
|
||||
bool congruentTo(const MDefinition *ins) const;
|
||||
MDefinition *foldsTo(TempAllocator &alloc);
|
||||
|
||||
AliasSet getAliasSet() const {
|
||||
return isConstant_ ? AliasSet::None() : AliasSet::Load(AliasSet::AsmJSGlobalVar);
|
||||
|
@ -240,7 +240,7 @@ MSG_DEF(JSMSG_SYMBOL_TO_STRING, 186, 0, JSEXN_TYPEERR, "can't convert symb
|
||||
MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 187, 0, JSEXN_ERR, "Cannot track object allocation, because other tools are already doing so")
|
||||
MSG_DEF(JSMSG_INCOMPATIBLE_METHOD, 188, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}")
|
||||
MSG_DEF(JSMSG_SYMBOL_TO_PRIMITIVE, 189, 0, JSEXN_TYPEERR, "can't convert symbol object to primitive")
|
||||
MSG_DEF(JSMSG_UNUSED190, 190, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 190, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true")
|
||||
MSG_DEF(JSMSG_BAD_INDEX, 191, 0, JSEXN_RANGEERR, "invalid or out-of-range index")
|
||||
MSG_DEF(JSMSG_SELFHOSTED_TOP_LEVEL_LET,192,0, JSEXN_SYNTAXERR, "self-hosted code cannot contain top-level 'let' declarations")
|
||||
MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 193, 0, JSEXN_SYNTAXERR, "invalid for each loop")
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "vm/Debugger-inl.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jshashutil.h"
|
||||
@ -338,6 +340,7 @@ Breakpoint::nextInSite()
|
||||
|
||||
Debugger::Debugger(JSContext *cx, JSObject *dbg)
|
||||
: object(dbg), uncaughtExceptionHook(nullptr), enabled(true), trackingAllocationSites(false),
|
||||
allocationsLogLength(0), maxAllocationsLogLength(DEFAULT_MAX_ALLOCATIONS_LOG_LENGTH),
|
||||
frames(cx->runtime()), scripts(cx), sources(cx), objects(cx), environments(cx)
|
||||
{
|
||||
assertSameCompartment(cx, dbg);
|
||||
@ -350,6 +353,7 @@ Debugger::Debugger(JSContext *cx, JSObject *dbg)
|
||||
Debugger::~Debugger()
|
||||
{
|
||||
JS_ASSERT_IF(debuggees.initialized(), debuggees.empty());
|
||||
emptyAllocationsLog();
|
||||
|
||||
/*
|
||||
* Since the inactive state for this link is a singleton cycle, it's always
|
||||
@ -392,6 +396,19 @@ Debugger::fromChildJSObject(JSObject *obj)
|
||||
return fromJSObject(dbgobj);
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::hasMemory() const
|
||||
{
|
||||
return object->getReservedSlot(JSSLOT_DEBUG_MEMORY_INSTANCE).isObject();
|
||||
}
|
||||
|
||||
DebuggerMemory &
|
||||
Debugger::memory() const
|
||||
{
|
||||
JS_ASSERT(hasMemory());
|
||||
return object->getReservedSlot(JSSLOT_DEBUG_MEMORY_INSTANCE).toObject().as<DebuggerMemory>();
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::getScriptFrameWithIter(JSContext *cx, AbstractFramePtr frame,
|
||||
const ScriptFrameIter *maybeIter, MutableHandleValue vp)
|
||||
@ -1439,6 +1456,61 @@ Debugger::slowPathOnNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global
|
||||
JS_ASSERT(!cx->isExceptionPending());
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Debugger::slowPathOnLogAllocationSite(JSContext *cx, HandleSavedFrame frame,
|
||||
GlobalObject::DebuggerVector &dbgs)
|
||||
{
|
||||
JS_ASSERT(!dbgs.empty());
|
||||
mozilla::DebugOnly<Debugger **> begin = dbgs.begin();
|
||||
|
||||
for (Debugger **dbgp = dbgs.begin(); dbgp < dbgs.end(); dbgp++) {
|
||||
// The set of debuggers had better not change while we're iterating,
|
||||
// such that the vector gets reallocated.
|
||||
JS_ASSERT(dbgs.begin() == begin);
|
||||
|
||||
if ((*dbgp)->trackingAllocationSites &&
|
||||
(*dbgp)->enabled &&
|
||||
!(*dbgp)->appendAllocationSite(cx, frame))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::appendAllocationSite(JSContext *cx, HandleSavedFrame frame)
|
||||
{
|
||||
AutoCompartment ac(cx, object);
|
||||
RootedObject wrapped(cx, frame);
|
||||
if (!cx->compartment()->wrap(cx, &wrapped))
|
||||
return false;
|
||||
|
||||
AllocationSite *allocSite = cx->new_<AllocationSite>(wrapped);
|
||||
if (!allocSite)
|
||||
return false;
|
||||
|
||||
allocationsLog.insertBack(allocSite);
|
||||
|
||||
if (allocationsLogLength >= maxAllocationsLogLength) {
|
||||
js_delete(allocationsLog.getFirst());
|
||||
} else {
|
||||
allocationsLogLength++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Debugger::emptyAllocationsLog()
|
||||
{
|
||||
while (!allocationsLog.isEmpty())
|
||||
js_delete(allocationsLog.getFirst());
|
||||
allocationsLogLength = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** Debugger JSObjects **************************************************************************/
|
||||
|
||||
@ -1634,6 +1706,12 @@ Debugger::trace(JSTracer *trc)
|
||||
MarkObject(trc, &frameobj, "live Debugger.Frame");
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark every allocation site in our allocation log.
|
||||
*/
|
||||
for (AllocationSite *s = allocationsLog.getFirst(); s; s = s->getNext())
|
||||
MarkObject(trc, &s->frame, "allocation log SavedFrame");
|
||||
|
||||
/* Trace the weak map from JSScript instances to Debugger.Script objects. */
|
||||
scripts.trace(trc);
|
||||
|
||||
|
@ -14,14 +14,17 @@
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jsweakmap.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/SavedStacks.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
class Breakpoint;
|
||||
class DebuggerMemory;
|
||||
|
||||
/*
|
||||
* A weakmap that supports the keys being in different compartments to the
|
||||
@ -161,6 +164,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
friend class DebuggerMemory;
|
||||
friend class mozilla::LinkedListElement<Debugger>;
|
||||
friend bool (::JS_DefineDebuggerObject)(JSContext *cx, JS::HandleObject obj);
|
||||
friend bool SavedStacksMetadataCallback(JSContext *cx, JSObject **pmetadata);
|
||||
|
||||
public:
|
||||
enum Hook {
|
||||
@ -190,9 +194,25 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
GlobalObjectSet debuggees; /* Debuggee globals. Cross-compartment weak references. */
|
||||
js::HeapPtrObject uncaughtExceptionHook; /* Strong reference. */
|
||||
bool enabled;
|
||||
bool trackingAllocationSites;
|
||||
JSCList breakpoints; /* Circular list of all js::Breakpoints in this debugger */
|
||||
|
||||
struct AllocationSite : public mozilla::LinkedListElement<AllocationSite>
|
||||
{
|
||||
AllocationSite(HandleObject frame) : frame(frame) {
|
||||
JS_ASSERT(UncheckedUnwrap(frame)->is<SavedFrame>());
|
||||
};
|
||||
RelocatablePtrObject frame;
|
||||
};
|
||||
typedef mozilla::LinkedList<AllocationSite> AllocationSiteList;
|
||||
|
||||
bool trackingAllocationSites;
|
||||
AllocationSiteList allocationsLog;
|
||||
size_t allocationsLogLength;
|
||||
size_t maxAllocationsLogLength;
|
||||
static const size_t DEFAULT_MAX_ALLOCATIONS_LOG_LENGTH = 5000;
|
||||
bool appendAllocationSite(JSContext *cx, HandleSavedFrame frame);
|
||||
void emptyAllocationsLog();
|
||||
|
||||
/*
|
||||
* If this Debugger is enabled, and has a onNewGlobalObject handler, then
|
||||
* this link is inserted into the circular list headed by
|
||||
@ -359,6 +379,8 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
static void slowPathOnNewScript(JSContext *cx, HandleScript script,
|
||||
GlobalObject *compileAndGoGlobal);
|
||||
static void slowPathOnNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
|
||||
static bool slowPathOnLogAllocationSite(JSContext *cx, HandleSavedFrame frame,
|
||||
GlobalObject::DebuggerVector &dbgs);
|
||||
static JSTrapStatus dispatchHook(JSContext *cx, MutableHandleValue vp, Hook which);
|
||||
|
||||
JSTrapStatus fireDebuggerStatement(JSContext *cx, MutableHandleValue vp);
|
||||
@ -408,6 +430,9 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
static inline Debugger *fromJSObject(JSObject *obj);
|
||||
static Debugger *fromChildJSObject(JSObject *obj);
|
||||
|
||||
bool hasMemory() const;
|
||||
DebuggerMemory &memory() const;
|
||||
|
||||
/*********************************** Methods for interaction with the GC. */
|
||||
|
||||
/*
|
||||
@ -441,6 +466,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
static inline void onNewScript(JSContext *cx, HandleScript script,
|
||||
GlobalObject *compileAndGoGlobal);
|
||||
static inline void onNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
|
||||
static inline bool onLogAllocationSite(JSContext *cx, HandleSavedFrame frame);
|
||||
static JSTrapStatus onTrap(JSContext *cx, MutableHandleValue vp);
|
||||
static JSTrapStatus onSingleStep(JSContext *cx, MutableHandleValue vp);
|
||||
static bool handleBaselineOsr(JSContext *cx, InterpreterFrame *from, jit::BaselineFrame *to);
|
||||
@ -758,6 +784,15 @@ Debugger::onNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global)
|
||||
Debugger::slowPathOnNewGlobalObject(cx, global);
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::onLogAllocationSite(JSContext *cx, HandleSavedFrame frame)
|
||||
{
|
||||
GlobalObject::DebuggerVector *dbgs = frame->global().getDebuggers();
|
||||
if (!dbgs || dbgs->empty())
|
||||
return true;
|
||||
return Debugger::slowPathOnLogAllocationSite(cx, frame, *dbgs);
|
||||
}
|
||||
|
||||
extern bool
|
||||
EvaluateInEnv(JSContext *cx, Handle<Env*> env, HandleValue thisv, AbstractFramePtr frame,
|
||||
mozilla::Range<const jschar> chars, const char *filename, unsigned lineno,
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "vm/DebuggerMemory.h"
|
||||
|
||||
#include "jscompartment.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/SavedStacks.h"
|
||||
@ -31,6 +32,13 @@ DebuggerMemory::create(JSContext *cx, Debugger *dbg)
|
||||
return &memory->as<DebuggerMemory>();
|
||||
}
|
||||
|
||||
Debugger *
|
||||
DebuggerMemory::getDebugger()
|
||||
{
|
||||
const Value &dbgVal = getReservedSlot(JSSLOT_DEBUGGER);
|
||||
return Debugger::fromJSObject(&dbgVal.toObject());
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
DebuggerMemory::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -51,12 +59,6 @@ DebuggerMemory::construct(JSContext *cx, unsigned argc, Value *vp)
|
||||
JS_EnumerateStub, // enumerate
|
||||
JS_ResolveStub, // resolve
|
||||
JS_ConvertStub, // convert
|
||||
|
||||
nullptr, // finalize
|
||||
nullptr, // call
|
||||
nullptr, // hasInstance
|
||||
nullptr, // construct
|
||||
nullptr // trace
|
||||
};
|
||||
|
||||
/* static */ DebuggerMemory *
|
||||
@ -108,12 +110,6 @@ DebuggerMemory::checkThis(JSContext *cx, CallArgs &args, const char *fnName)
|
||||
if (!memory) \
|
||||
return false
|
||||
|
||||
Debugger *
|
||||
DebuggerMemory::getDebugger()
|
||||
{
|
||||
return Debugger::fromJSObject(&getReservedSlot(JSSLOT_DEBUGGER).toObject());
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
DebuggerMemory::setTrackingAllocationSites(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -149,6 +145,9 @@ DebuggerMemory::setTrackingAllocationSites(JSContext *cx, unsigned argc, Value *
|
||||
}
|
||||
}
|
||||
|
||||
if (!enabling)
|
||||
dbg->emptyAllocationsLog();
|
||||
|
||||
dbg->trackingAllocationSites = enabling;
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
@ -162,11 +161,81 @@ DebuggerMemory::getTrackingAllocationSites(JSContext *cx, unsigned argc, Value *
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
DebuggerMemory::drainAllocationsLog(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
THIS_DEBUGGER_MEMORY(cx, argc, vp, "drainAllocationsLog", args, memory);
|
||||
Debugger* dbg = memory->getDebugger();
|
||||
|
||||
if (!dbg->trackingAllocationSites) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_NOT_TRACKING_ALLOCATIONS,
|
||||
"drainAllocationsLog");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t length = dbg->allocationsLogLength;
|
||||
|
||||
RootedObject result(cx, NewDenseAllocatedArray(cx, length));
|
||||
if (!result)
|
||||
return false;
|
||||
result->ensureDenseInitializedLength(cx, 0, length);
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
Debugger::AllocationSite *allocSite = dbg->allocationsLog.popFirst();
|
||||
result->setDenseElement(i, ObjectValue(*allocSite->frame));
|
||||
js_delete(allocSite);
|
||||
}
|
||||
|
||||
dbg->allocationsLogLength = 0;
|
||||
args.rval().setObject(*result);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
DebuggerMemory::getMaxAllocationsLogLength(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(get maxAllocationsLogLength)", args, memory);
|
||||
args.rval().setInt32(memory->getDebugger()->maxAllocationsLogLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
DebuggerMemory::setMaxAllocationsLogLength(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
THIS_DEBUGGER_MEMORY(cx, argc, vp, "(set maxAllocationsLogLength)", args, memory);
|
||||
if (!args.requireAtLeast(cx, "(set maxAllocationsLogLength)", 1))
|
||||
return false;
|
||||
|
||||
int32_t max;
|
||||
if (!ToInt32(cx, args[0], &max))
|
||||
return false;
|
||||
|
||||
if (max < 1) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
|
||||
"(set maxAllocationsLogLength)'s parameter",
|
||||
"not a positive integer");
|
||||
return false;
|
||||
}
|
||||
|
||||
Debugger *dbg = memory->getDebugger();
|
||||
dbg->maxAllocationsLogLength = max;
|
||||
|
||||
while (dbg->allocationsLogLength > dbg->maxAllocationsLogLength) {
|
||||
js_delete(dbg->allocationsLog.getFirst());
|
||||
dbg->allocationsLogLength--;
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ const JSPropertySpec DebuggerMemory::properties[] = {
|
||||
JS_PSGS("trackingAllocationSites", getTrackingAllocationSites, setTrackingAllocationSites, 0),
|
||||
JS_PSGS("maxAllocationsLogLength", getMaxAllocationsLogLength, setMaxAllocationsLogLength, 0),
|
||||
JS_PS_END
|
||||
};
|
||||
|
||||
/* static */ const JSFunctionSpec DebuggerMemory::methods[] = {
|
||||
JS_FN("drainAllocationsLog", DebuggerMemory::drainAllocationsLog, 0, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
@ -37,6 +37,9 @@ class DebuggerMemory : public JSObject {
|
||||
|
||||
static bool setTrackingAllocationSites(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool getTrackingAllocationSites(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool drainAllocationsLog(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool setMaxAllocationsLogLength(JSContext*cx, unsigned argc, Value *vp);
|
||||
static bool getMaxAllocationsLogLength(JSContext*cx, unsigned argc, Value *vp);
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "gc/Marking.h"
|
||||
#include "js/Vector.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/StringBuffer.h"
|
||||
|
||||
@ -734,7 +735,8 @@ SavedStacksMetadataCallback(JSContext *cx, JSObject **pmetadata)
|
||||
if (!cx->compartment()->savedStacks().saveCurrentStack(cx, &frame))
|
||||
return false;
|
||||
*pmetadata = frame;
|
||||
return true;
|
||||
|
||||
return Debugger::onLogAllocationSite(cx, frame);
|
||||
}
|
||||
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
|
@ -330,8 +330,8 @@ inDOMView::GetCellProperties(int32_t row, nsITreeColumn* col,
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
if (mShowAccessibleNodes) {
|
||||
nsCOMPtr<nsIAccessibilityService> accService(
|
||||
do_GetService("@mozilla.org/accessibilityService;1"));
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
services::GetAccessibilityService();
|
||||
NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
|
@ -64,7 +64,7 @@ fuzzy(1,139) fuzzy-if(OSX,2,4478) == border-image-radial-gradient-slice-fill-2.h
|
||||
fuzzy(1,9000) == border-image-radial-gradient-slice-width.html border-image-radial-gradient-slice-width-ref.html
|
||||
|
||||
# OS X failures tracked in bug 957025
|
||||
fails-if(OSX) == border-image-repeating-linear-gradient.html border-image-repeating-linear-gradient-ref.html
|
||||
== border-image-repeating-linear-gradient.html border-image-repeating-linear-gradient-ref.html
|
||||
fuzzy(1,5608) fails-if(OSX) == border-image-repeating-linear-gradient-slice-fill-2.html border-image-repeating-linear-gradient-slice-fill-2-ref.html
|
||||
fuzzy(1,19200) fails-if(OSX) == border-image-repeating-linear-gradient-repeat-round-2.html border-image-repeating-linear-gradient-repeat-round-2-ref.html
|
||||
|
||||
@ -75,7 +75,7 @@ fuzzy(1,1357) fails-if(OSX) == border-image-repeating-radial-gradient-slice-fill
|
||||
fuzzy(1,1058) fails-if(OSX) == border-image-repeating-radial-gradient-slice-fill-2.html border-image-repeating-radial-gradient-slice-fill-2-ref.html
|
||||
fuzzy(1,602) fails-if(OSX) == border-image-repeating-radial-gradient-width.html border-image-repeating-radial-gradient-width-ref.html
|
||||
fuzzy(3,18000) fails-if(OSX) == border-image-repeating-radial-gradient-slice-width.html border-image-repeating-radial-gradient-slice-width-ref.html
|
||||
fails-if(OSX) == border-image-repeating-radial-gradient-repeat-repeat-2.html border-image-repeating-radial-gradient-repeat-repeat-2-ref.html
|
||||
== border-image-repeating-radial-gradient-repeat-repeat-2.html border-image-repeating-radial-gradient-repeat-repeat-2-ref.html
|
||||
fuzzy(1,1054) fails-if(OSX) == border-image-repeating-radial-gradient-repeat-round-2.html border-image-repeating-radial-gradient-repeat-round-2-ref.html
|
||||
|
||||
# border-image-source (-moz-)element
|
||||
|
20
layout/reftests/bugs/1049499-1-ref.html
Normal file
20
layout/reftests/bugs/1049499-1-ref.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Choose the correct gradient repeat count even when there's a non-identity pattern matrix</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div {
|
||||
width: 30px;
|
||||
height: 40px;
|
||||
background-image: repeating-linear-gradient(-36.8698976deg, blue, blue 5px, lime 5px, lime 10px);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div></div>
|
27
layout/reftests/bugs/1049499-1.html
Normal file
27
layout/reftests/bugs/1049499-1.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Choose the correct gradient repeat count even when there's a non-identity pattern matrix</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div {
|
||||
box-sizing: border-box;
|
||||
width: 240px;
|
||||
height: 320px;
|
||||
|
||||
/* Scale a 240x320 gradient down by a factor of 8 into a 30x40 border image. */
|
||||
/* 240x320 gives a diagonal of 400px, so we should get 5 repetitions of a 80px long gradient. */
|
||||
/* tan(36.8698976deg) == 240 / 320 */
|
||||
border-left: 30px solid;
|
||||
border-top: 40px solid;
|
||||
border-image: repeating-linear-gradient(-36.8698976deg, blue, blue 40px, lime 40px, lime 80px);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div></div>
|
@ -1820,3 +1820,4 @@ pref(browser.display.use_document_fonts,0) == 1022481-1.html 1022481-1-ref.html
|
||||
== 1024473-1.html 1024473-1-ref.html
|
||||
== 1042104-1.html 1042104-1-ref.html
|
||||
== 1044198-1.html 1044198-1-ref.html
|
||||
== 1049499-1.html 1049499-1-ref.html
|
||||
|
@ -64,6 +64,7 @@ nsSliderFrame::nsSliderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
nsBoxFrame(aPresShell, aContext),
|
||||
mCurPos(0),
|
||||
mChange(0),
|
||||
mDragFinished(true),
|
||||
mUserChanged(false)
|
||||
{
|
||||
}
|
||||
@ -417,6 +418,11 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mDragFinished && !isDraggingThumb()) {
|
||||
StopDrag();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame* scrollbarBox = GetScrollbar();
|
||||
nsCOMPtr<nsIContent> scrollbar;
|
||||
scrollbar = GetContentOfBox(scrollbarBox);
|
||||
@ -487,13 +493,7 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
case NS_TOUCH_END:
|
||||
case NS_MOUSE_BUTTON_UP:
|
||||
if (ShouldScrollForEvent(aEvent)) {
|
||||
// stop capturing
|
||||
AddListener();
|
||||
DragThumb(false);
|
||||
if (mChange) {
|
||||
StopRepeat();
|
||||
mChange = 0;
|
||||
}
|
||||
StopDrag();
|
||||
//we MUST call nsFrame HandleEvent for mouse ups to maintain the selection state and capture state.
|
||||
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||
}
|
||||
@ -876,9 +876,23 @@ nsSliderFrame::StartDrag(nsIDOMEvent* aEvent)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSliderFrame::StopDrag()
|
||||
{
|
||||
AddListener();
|
||||
DragThumb(false);
|
||||
if (mChange) {
|
||||
StopRepeat();
|
||||
mChange = 0;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsSliderFrame::DragThumb(bool aGrabMouseEvents)
|
||||
{
|
||||
mDragFinished = !aGrabMouseEvents;
|
||||
|
||||
// inform the parent <scale> that a drag is beginning or ending
|
||||
nsIFrame* parent = GetParent();
|
||||
if (parent) {
|
||||
|
@ -97,6 +97,7 @@ public:
|
||||
nsIFrame* aOldFrame) MOZ_OVERRIDE;
|
||||
|
||||
nsresult StartDrag(nsIDOMEvent* aEvent);
|
||||
nsresult StopDrag();
|
||||
|
||||
static int32_t GetCurrentPosition(nsIContent* content);
|
||||
static int32_t GetMinPosition(nsIContent* content);
|
||||
@ -173,6 +174,8 @@ private:
|
||||
|
||||
nscoord mChange;
|
||||
|
||||
bool mDragFinished;
|
||||
|
||||
// true if an attribute change has been caused by the user manipulating the
|
||||
// slider. This allows notifications to tell how a slider's current position
|
||||
// was changed.
|
||||
|
@ -515,7 +515,6 @@ main(int argc, char * argv[])
|
||||
test_init_destroy_multiple_contexts();
|
||||
test_init_destroy_stream();
|
||||
test_init_destroy_multiple_streams();
|
||||
test_init_destroy_multiple_contexts_and_streams();
|
||||
test_basic_stream_operations();
|
||||
test_stream_position();
|
||||
|
||||
@ -525,6 +524,8 @@ main(int argc, char * argv[])
|
||||
* and is not documented as a possible return value for this call. Hence, we
|
||||
* try to limit the number of streams we create in this test. */
|
||||
if (!is_windows_7()) {
|
||||
test_init_destroy_multiple_contexts_and_streams();
|
||||
|
||||
delay_callback = 0;
|
||||
test_init_start_stop_destroy_multiple_streams(0, 0);
|
||||
test_init_start_stop_destroy_multiple_streams(1, 0);
|
||||
|
@ -10,8 +10,12 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function onWindowLoad()
|
||||
{
|
||||
function onWindowLoad() {
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.unsafe_legacy_crypto.enabled", true]]},
|
||||
runTest);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
// Does it work at all?
|
||||
try {
|
||||
var crmfObject = crypto.generateCRMFRequest("CN=undefined", "regToken",
|
||||
|
@ -83,6 +83,8 @@ skip-if = os == "win" # Intermittent failures, bug 919016
|
||||
[test_bug585946.xul]
|
||||
[test_bug624329.xul]
|
||||
[test_bug792324.xul]
|
||||
[test_bug1048178.xul]
|
||||
skip-if = toolkit == "cocoa"
|
||||
[test_button.xul]
|
||||
[test_closemenu_attribute.xul]
|
||||
[test_colorpicker_popup.xul]
|
||||
|
86
toolkit/content/tests/chrome/test_bug1048178.xul
Normal file
86
toolkit/content/tests/chrome/test_bug1048178.xul
Normal file
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1048178
|
||||
-->
|
||||
<window title="Mozilla Bug 1048178"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml"/>
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1048178"
|
||||
target="_blank">Mozilla Bug 1048178</a>
|
||||
|
||||
<hbox>
|
||||
<scrollbar id="scroller"
|
||||
orient="horizontal"
|
||||
curpos="0"
|
||||
maxpos="500"
|
||||
pageincrement="500"
|
||||
width="500"
|
||||
style="margin:0"/>
|
||||
</hbox>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
/** Test for Bug 1048178 **/
|
||||
var scrollbarTester = {
|
||||
scrollbar: null,
|
||||
startTest: function() {
|
||||
this.scrollbar = $("scroller");
|
||||
this.setScrollToClick(false);
|
||||
this.testThumbDragging();
|
||||
SimpleTest.finish();
|
||||
},
|
||||
testThumbDragging: function() {
|
||||
var x = 400; // on the right half of the scroolbar
|
||||
var y = 5;
|
||||
|
||||
this.mousedown(x, y, 0);
|
||||
this.mousedown(x, y, 2);
|
||||
this.mouseup(x, y, 2);
|
||||
this.mouseup(x, y, 0);
|
||||
|
||||
var newPos = this.getPos(); // sould be '500'
|
||||
|
||||
this.mousedown(x, y, 0);
|
||||
this.mousemove(x-1, y, 0);
|
||||
this.mouseup(x-1, y, 0);
|
||||
|
||||
var newPos2 = this.getPos();
|
||||
ok(newPos2 < newPos,
|
||||
"Scrollbar thumb should follow the mouse when dragged.");
|
||||
},
|
||||
setScrollToClick: function(value) {
|
||||
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService);
|
||||
var uiBranch = prefService.getBranch("ui.");
|
||||
uiBranch.setIntPref("scrollToClick", value ? 1 : 0);
|
||||
},
|
||||
getPos: function() {
|
||||
return this.scrollbar.getAttribute("curpos");
|
||||
},
|
||||
mousedown: function(x, y, button) {
|
||||
synthesizeMouse(this.scrollbar, x, y, { type: "mousedown", 'button': button });
|
||||
},
|
||||
mousemove: function(x, y, button) {
|
||||
synthesizeMouse(this.scrollbar, x, y, { type: "mousemove", 'button': button });
|
||||
},
|
||||
mouseup: function(x, y, button) {
|
||||
synthesizeMouse(this.scrollbar, x, y, { type: "mouseup", 'button': button });
|
||||
}
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
setTimeout(function() { scrollbarTester.startTest(); }, 0);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
|
||||
]]></script>
|
||||
</window>
|
@ -4,11 +4,12 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import sys, subprocess
|
||||
import sys, subprocess, os
|
||||
|
||||
def NMSymbolicate(library, addresses):
|
||||
target_tools_prefix = os.environ.get("TARGET_TOOLS_PREFIX", "")
|
||||
args = [
|
||||
"nm", "-D", "-S", library
|
||||
target_tools_prefix + "nm", "-D", "-S", library
|
||||
]
|
||||
nm_lines = subprocess.check_output(args).split("\n")
|
||||
symbol_table = []
|
||||
|
@ -47,6 +47,8 @@ nsSystemStatusBarCocoa::RemoveItem(nsIDOMElement* aDOMElement)
|
||||
nsSystemStatusBarCocoa::StatusItem::StatusItem(nsStandaloneNativeMenu* aMenu)
|
||||
: mMenu(aMenu)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsSystemStatusBarCocoa::StatusItem);
|
||||
|
||||
NSMenu* nativeMenu = nil;
|
||||
mMenu->GetNativeMenu(reinterpret_cast<void**>(&nativeMenu));
|
||||
|
||||
@ -67,4 +69,6 @@ nsSystemStatusBarCocoa::StatusItem::~StatusItem()
|
||||
[[NSStatusBar systemStatusBar] removeStatusItem:mStatusItem];
|
||||
[mStatusItem release];
|
||||
mStatusItem = nil;
|
||||
|
||||
MOZ_COUNT_DTOR(nsSystemStatusBarCocoa::StatusItem);
|
||||
}
|
||||
|
@ -5882,7 +5882,7 @@ nsWindow::DispatchEventToRootAccessible(uint32_t aEventType)
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
do_GetService("@mozilla.org/accessibilityService;1");
|
||||
services::GetAccessibilityService();
|
||||
if (!accService) {
|
||||
return;
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ skip-if = toolkit != "cocoa"
|
||||
skip-if = toolkit != "cocoa"
|
||||
[test_native_key_bindings_mac.html]
|
||||
skip-if = toolkit != "cocoa"
|
||||
[test_system_status_bar.xul]
|
||||
skip-if = toolkit != "cocoa"
|
||||
|
||||
# Windows
|
||||
# taskbar_previews.xul
|
||||
|
57
widget/tests/test_system_status_bar.xul
Normal file
57
widget/tests/test_system_status_bar.xul
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<window title="Testing composition, text and query content events"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<menupopup id="menuContainer">
|
||||
<menu id="menu1" image="data:image/svg+xml,<svg%20xmlns="http://www.w3.org/2000/svg"%20width="32"%20height="32"><circle%20cx="16"%20cy="16"%20r="16"/></svg>">
|
||||
<menupopup>
|
||||
<menuitem label="Item 1 in menu 1"/>
|
||||
<menuitem label="Item 2 in menu 1"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menu id="menu2" image="data:image/svg+xml,<svg%20xmlns="http://www.w3.org/2000/svg"%20width="32"%20height="32"><path%20d="M0 16 L 16 0 L 32 16 L 16 32 Z"/></svg>">
|
||||
<menupopup>
|
||||
<menuitem label="Item 1 in menu 2"/>
|
||||
<menuitem label="Item 2 in menu 2"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
|
||||
let systemStatusBar = Cc["@mozilla.org/widget/macsystemstatusbar;1"].getService(Ci.nsISystemStatusBar);
|
||||
ok(systemStatusBar, "should have got an nsISystemStatusBar instance");
|
||||
|
||||
let menu1 = document.getElementById("menu1");
|
||||
let menu2 = document.getElementById("menu2");
|
||||
|
||||
// Add and remove the item, just to get basic leak testing coverage.
|
||||
systemStatusBar.addItem(menu1);
|
||||
systemStatusBar.removeItem(menu1);
|
||||
|
||||
// Make sure that calling addItem twice with the same element doesn't leak.
|
||||
systemStatusBar.addItem(menu2);
|
||||
systemStatusBar.addItem(menu2);
|
||||
systemStatusBar.removeItem(menu2);
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
Loading…
Reference in New Issue
Block a user