115 lines
3.2 KiB
JavaScript
115 lines
3.2 KiB
JavaScript
/* 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/. */
|
|
|
|
function TestInterfaceAll() {}
|
|
TestInterfaceAll.prototype = {
|
|
QueryInterface: ChromeUtils.generateQI(["nsIXPCTestInterfaceA",
|
|
"nsIXPCTestInterfaceB",
|
|
"nsIXPCTestInterfaceC"]),
|
|
|
|
/* nsIXPCTestInterfaceA / nsIXPCTestInterfaceB */
|
|
name: "TestInterfaceAllDefaultName",
|
|
|
|
/* nsIXPCTestInterfaceC */
|
|
someInteger: 42
|
|
};
|
|
|
|
function newWrappedJS() {
|
|
return xpcWrap(new TestInterfaceAll());
|
|
}
|
|
|
|
function run_test() {
|
|
// Shortcut the interfaces we're using.
|
|
var ifs = {
|
|
a: Ci['nsIXPCTestInterfaceA'],
|
|
b: Ci['nsIXPCTestInterfaceB'],
|
|
c: Ci['nsIXPCTestInterfaceC']
|
|
};
|
|
|
|
// Run through the logic a few times.
|
|
for (let i = 0; i < 2; ++i)
|
|
play_with_tearoffs(ifs);
|
|
}
|
|
|
|
function play_with_tearoffs(ifs) {
|
|
|
|
// Allocate a bunch of objects, QI-ed to B.
|
|
var instances = [];
|
|
for (var i = 0; i < 300; ++i)
|
|
instances.push(newWrappedJS().QueryInterface(ifs.b));
|
|
|
|
// Nothing to collect.
|
|
gc();
|
|
|
|
// QI them to A.
|
|
instances.forEach(function(v, i, a) { v.QueryInterface(ifs.a); });
|
|
|
|
// QI them to C.
|
|
instances.forEach(function(v, i, a) { v.QueryInterface(ifs.c); });
|
|
|
|
// Check
|
|
Assert.ok('name' in instances[10], 'Have the prop from A/B');
|
|
Assert.ok('someInteger' in instances[10], 'Have the prop from C');
|
|
|
|
// Grab tearoff reflections for a and b.
|
|
var aTearOffs = instances.map(function(v, i, a) { return v.nsIXPCTestInterfaceA; } );
|
|
var bTearOffs = instances.map(function(v, i, a) { return v.nsIXPCTestInterfaceB; } );
|
|
|
|
// Check
|
|
Assert.ok('name' in aTearOffs[1], 'Have the prop from A');
|
|
Assert.ok(!('someInteger' in aTearOffs[1]), 'Dont have the prop from C');
|
|
|
|
// Nothing to collect.
|
|
gc();
|
|
|
|
// Null out every even instance pointer.
|
|
for (var i = 0; i < instances.length; ++i)
|
|
if (i % 2 == 0)
|
|
instances[i] = null;
|
|
|
|
// Nothing to collect, since we still have the A and B tearoff reflections.
|
|
gc();
|
|
|
|
// Null out A tearoff reflections that are a multiple of 3.
|
|
for (var i = 0; i < aTearOffs.length; ++i)
|
|
if (i % 3 == 0)
|
|
aTearOffs[i] = null;
|
|
|
|
// Nothing to collect, since we still have the B tearoff reflections.
|
|
gc();
|
|
|
|
// Null out B tearoff reflections that are a multiple of 5.
|
|
for (var i = 0; i < bTearOffs.length; ++i)
|
|
if (i % 5 == 0)
|
|
bTearOffs[i] = null;
|
|
|
|
// This should collect every 30th object (indices that are multiples of 2, 3, and 5).
|
|
gc();
|
|
|
|
// Kill the b tearoffs entirely.
|
|
bTearOffs = 0;
|
|
|
|
// Collect more.
|
|
gc();
|
|
|
|
// Get C tearoffs.
|
|
var cTearOffs = instances.map(function(v, i, a) { return v ? v.nsIXPCTestInterfaceC : null; } );
|
|
|
|
// Check.
|
|
Assert.ok(!('name' in cTearOffs[1]), 'Dont have the prop from A');
|
|
Assert.ok('someInteger' in cTearOffs[1], 'have the prop from C');
|
|
|
|
// Null out the a tearoffs.
|
|
aTearOffs = null;
|
|
|
|
// Collect all even indices.
|
|
gc();
|
|
|
|
// Collect all indices.
|
|
instances = null;
|
|
gc();
|
|
|
|
// Give ourselves a pat on the back. :-)
|
|
Assert.ok(true, "Got all the way through without crashing!");
|
|
}
|