1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
6 // Check to see if a weak reference is dead.
7 let weak_ref_dead = function (r) {
8 return !SpecialPowers.nondeterministicGetWeakMapKeys(r).length;
11 add_task(async function cc_xpcwn_dead() {
12 // This test demonstrates that a JS reflector for an XPCOM object
13 // (implemented via XPCWrappedNative) can be used as a weak map key, but it
14 // won't persist across a GC/CC if there are no other references to the key in
15 // JS. It would be nice if it did work, in which case we could delete this
16 // test, but it would be difficult to implement.
18 let wnMap = new WeakMap();
20 // Create a new C++ XPCOM container.
21 let container = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
24 // Create a new C++ XPCOM object, with a new JS reflector.
25 let str = Cc["@mozilla.org/supports-string;1"].createInstance(
29 // Set the string data so we can recognize it later.
30 str.data = "canary123";
32 // Store the C++ object in the C++ container.
33 container.appendElement(str);
34 is(container.Count(), 1, "The array should have one element");
36 // Use the JS reflector as a weak map key.
38 ok(!weak_ref_dead(wnMap), "weak map should have an entry");
40 // Make sure there are no references to the JS reflector.
44 // Clean up the JS reflector.
45 SpecialPowers.forceGC();
46 SpecialPowers.forceCC();
48 ok(weak_ref_dead(wnMap), "The JS reflector has been freed.");
50 // Make a new JS reflector for the C++ XPCOM object.
51 let str2 = container.GetElementAt(0).QueryInterface(Ci.nsISupportsString);
53 is(str2.data, "canary123", "The C++ object we created still exists.");
56 add_task(async function cc_xpcwn_live() {
57 // This test is a slight variation of the previous one. It keeps a reference
58 // to the JS reflector for the C++ object, and shows that this keeps it from
59 // being removed from the weak map. This is mostly to show why it will work
60 // under some conditions.
62 let wnMap = new WeakMap();
64 // Create a new C++ XPCOM container.
65 let container = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
67 // Create a new C++ XPCOM object, with a new JS reflector, and hold alive
69 let str = Cc["@mozilla.org/supports-string;1"].createInstance(
73 // Set the string data so we can recognize it later.
74 str.data = "canary345";
76 // Store the C++ object in the C++ container.
77 container.appendElement(str);
78 is(container.Count(), 1, "The array should have one element");
80 // Use the JS reflector as a weak map key.
82 ok(!weak_ref_dead(wnMap), "weak map should have an entry");
84 // Clean up the JS reflector.
85 SpecialPowers.forceGC();
86 SpecialPowers.forceCC();
88 ok(!weak_ref_dead(wnMap), "The JS reflector hasn't been freed.");
90 // Get a JS reflector from scratch for the C++ XPCOM object.
91 let str2 = container.GetElementAt(0).QueryInterface(Ci.nsISupportsString);
92 is(str, str2, "The JS reflector is the same");
93 is(str2.data, "canary345", "The C++ object hasn't changed");