diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /js/xpconnect/tests/browser/browser_weak_xpcwn.js | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/xpconnect/tests/browser/browser_weak_xpcwn.js')
-rw-r--r-- | js/xpconnect/tests/browser/browser_weak_xpcwn.js | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/js/xpconnect/tests/browser/browser_weak_xpcwn.js b/js/xpconnect/tests/browser/browser_weak_xpcwn.js new file mode 100644 index 0000000000..fc0fb502e0 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_weak_xpcwn.js @@ -0,0 +1,94 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Check to see if a weak reference is dead. +let weak_ref_dead = function (r) { + return !SpecialPowers.nondeterministicGetWeakMapKeys(r).length; +}; + +add_task(async function cc_xpcwn_dead() { + // This test demonstrates that a JS reflector for an XPCOM object + // (implemented via XPCWrappedNative) can be used as a weak map key, but it + // won't persist across a GC/CC if there are no other references to the key in + // JS. It would be nice if it did work, in which case we could delete this + // test, but it would be difficult to implement. + + let wnMap = new WeakMap(); + + // Create a new C++ XPCOM container. + let container = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); + + { + // Create a new C++ XPCOM object, with a new JS reflector. + let str = Cc["@mozilla.org/supports-string;1"].createInstance( + Ci.nsISupportsString + ); + + // Set the string data so we can recognize it later. + str.data = "canary123"; + + // Store the C++ object in the C++ container. + container.appendElement(str); + is(container.Count(), 1, "The array should have one element"); + + // Use the JS reflector as a weak map key. + wnMap.set(str, {}); + ok(!weak_ref_dead(wnMap), "weak map should have an entry"); + + // Make sure there are no references to the JS reflector. + str = null; + } + + // Clean up the JS reflector. + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + + ok(weak_ref_dead(wnMap), "The JS reflector has been freed."); + + // Make a new JS reflector for the C++ XPCOM object. + let str2 = container.GetElementAt(0).QueryInterface(Ci.nsISupportsString); + + is(str2.data, "canary123", "The C++ object we created still exists."); +}); + +add_task(async function cc_xpcwn_live() { + // This test is a slight variation of the previous one. It keeps a reference + // to the JS reflector for the C++ object, and shows that this keeps it from + // being removed from the weak map. This is mostly to show why it will work + // under some conditions. + + let wnMap = new WeakMap(); + + // Create a new C++ XPCOM container. + let container = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); + + // Create a new C++ XPCOM object, with a new JS reflector, and hold alive + // the reflector. + let str = Cc["@mozilla.org/supports-string;1"].createInstance( + Ci.nsISupportsString + ); + + // Set the string data so we can recognize it later. + str.data = "canary345"; + + // Store the C++ object in the C++ container. + container.appendElement(str); + is(container.Count(), 1, "The array should have one element"); + + // Use the JS reflector as a weak map key. + wnMap.set(str, {}); + ok(!weak_ref_dead(wnMap), "weak map should have an entry"); + + // Clean up the JS reflector. + SpecialPowers.forceGC(); + SpecialPowers.forceCC(); + + ok(!weak_ref_dead(wnMap), "The JS reflector hasn't been freed."); + + // Get a JS reflector from scratch for the C++ XPCOM object. + let str2 = container.GetElementAt(0).QueryInterface(Ci.nsISupportsString); + is(str, str2, "The JS reflector is the same"); + is(str2.data, "canary345", "The C++ object hasn't changed"); +}); |