tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_weak_xpcwn.js (3232B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Check to see if a weak reference is dead.
      7 let weak_ref_dead = function (r) {
      8  return !SpecialPowers.nondeterministicGetWeakMapKeys(r).length;
      9 };
     10 
     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.
     17 
     18  let wnMap = new WeakMap();
     19 
     20  // Create a new C++ XPCOM container.
     21  let container = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
     22 
     23  {
     24    // Create a new C++ XPCOM object, with a new JS reflector.
     25    let str = Cc["@mozilla.org/supports-string;1"].createInstance(
     26      Ci.nsISupportsString
     27    );
     28 
     29    // Set the string data so we can recognize it later.
     30    str.data = "canary123";
     31 
     32    // Store the C++ object in the C++ container.
     33    container.appendElement(str);
     34    is(container.Count(), 1, "The array should have one element");
     35 
     36    // Use the JS reflector as a weak map key.
     37    wnMap.set(str, {});
     38    ok(!weak_ref_dead(wnMap), "weak map should have an entry");
     39 
     40    // Make sure there are no references to the JS reflector.
     41    str = null;
     42  }
     43 
     44  // Clean up the JS reflector.
     45  SpecialPowers.forceGC();
     46  SpecialPowers.forceCC();
     47 
     48  ok(weak_ref_dead(wnMap), "The JS reflector has been freed.");
     49 
     50  // Make a new JS reflector for the C++ XPCOM object.
     51  let str2 = container.GetElementAt(0).QueryInterface(Ci.nsISupportsString);
     52 
     53  is(str2.data, "canary123", "The C++ object we created still exists.");
     54 });
     55 
     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.
     61 
     62  let wnMap = new WeakMap();
     63 
     64  // Create a new C++ XPCOM container.
     65  let container = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
     66 
     67  // Create a new C++ XPCOM object, with a new JS reflector, and hold alive
     68  // the reflector.
     69  let str = Cc["@mozilla.org/supports-string;1"].createInstance(
     70    Ci.nsISupportsString
     71  );
     72 
     73  // Set the string data so we can recognize it later.
     74  str.data = "canary345";
     75 
     76  // Store the C++ object in the C++ container.
     77  container.appendElement(str);
     78  is(container.Count(), 1, "The array should have one element");
     79 
     80  // Use the JS reflector as a weak map key.
     81  wnMap.set(str, {});
     82  ok(!weak_ref_dead(wnMap), "weak map should have an entry");
     83 
     84  // Clean up the JS reflector.
     85  SpecialPowers.forceGC();
     86  SpecialPowers.forceCC();
     87 
     88  ok(!weak_ref_dead(wnMap), "The JS reflector hasn't been freed.");
     89 
     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");
     94 });