addon-sdk/source/lib/sdk/lang/weak-set.js

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:240243051189
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 module.metadata = {
6 "stability": "experimental"
7 };
8
9 "use strict";
10
11 const { Cu } = require("chrome");
12
13 function makeGetterFor(Type) {
14 let cache = new WeakMap();
15
16 return function getFor(target) {
17 if (!cache.has(target))
18 cache.set(target, new Type());
19
20 return cache.get(target);
21 }
22 }
23
24 let getLookupFor = makeGetterFor(WeakMap);
25 let getRefsFor = makeGetterFor(Set);
26
27 function add(target, value) {
28 if (has(target, value))
29 return;
30
31 getLookupFor(target).set(value, true);
32 getRefsFor(target).add(Cu.getWeakReference(value));
33 }
34 exports.add = add;
35
36 function remove(target, value) {
37 getLookupFor(target).delete(value);
38 }
39 exports.remove = remove;
40
41 function has(target, value) {
42 return getLookupFor(target).has(value);
43 }
44 exports.has = has;
45
46 function clear(target) {
47 getLookupFor(target).clear();
48 getRefsFor(target).clear();
49 }
50 exports.clear = clear;
51
52 function iterator(target) {
53 let refs = getRefsFor(target);
54
55 for (let ref of refs) {
56 let value = ref.get();
57
58 // If `value` is already gc'ed, it would be `null`.
59 // The `has` function is using a WeakMap as lookup table, so passing `null`
60 // would raise an exception because WeakMap accepts as value only non-null
61 // object.
62 // Plus, if `value` is already gc'ed, we do not have to take it in account
63 // during the iteration, and remove it from the references.
64 if (value !== null && has(target, value))
65 yield value;
66 else
67 refs.delete(ref);
68 }
69 }
70 exports.iterator = iterator;

mercurial