1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/lib/sdk/lang/weak-set.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,70 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +module.metadata = { 1.9 + "stability": "experimental" 1.10 +}; 1.11 + 1.12 +"use strict"; 1.13 + 1.14 +const { Cu } = require("chrome"); 1.15 + 1.16 +function makeGetterFor(Type) { 1.17 + let cache = new WeakMap(); 1.18 + 1.19 + return function getFor(target) { 1.20 + if (!cache.has(target)) 1.21 + cache.set(target, new Type()); 1.22 + 1.23 + return cache.get(target); 1.24 + } 1.25 +} 1.26 + 1.27 +let getLookupFor = makeGetterFor(WeakMap); 1.28 +let getRefsFor = makeGetterFor(Set); 1.29 + 1.30 +function add(target, value) { 1.31 + if (has(target, value)) 1.32 + return; 1.33 + 1.34 + getLookupFor(target).set(value, true); 1.35 + getRefsFor(target).add(Cu.getWeakReference(value)); 1.36 +} 1.37 +exports.add = add; 1.38 + 1.39 +function remove(target, value) { 1.40 + getLookupFor(target).delete(value); 1.41 +} 1.42 +exports.remove = remove; 1.43 + 1.44 +function has(target, value) { 1.45 + return getLookupFor(target).has(value); 1.46 +} 1.47 +exports.has = has; 1.48 + 1.49 +function clear(target) { 1.50 + getLookupFor(target).clear(); 1.51 + getRefsFor(target).clear(); 1.52 +} 1.53 +exports.clear = clear; 1.54 + 1.55 +function iterator(target) { 1.56 + let refs = getRefsFor(target); 1.57 + 1.58 + for (let ref of refs) { 1.59 + let value = ref.get(); 1.60 + 1.61 + // If `value` is already gc'ed, it would be `null`. 1.62 + // The `has` function is using a WeakMap as lookup table, so passing `null` 1.63 + // would raise an exception because WeakMap accepts as value only non-null 1.64 + // object. 1.65 + // Plus, if `value` is already gc'ed, we do not have to take it in account 1.66 + // during the iteration, and remove it from the references. 1.67 + if (value !== null && has(target, value)) 1.68 + yield value; 1.69 + else 1.70 + refs.delete(ref); 1.71 + } 1.72 +} 1.73 +exports.iterator = iterator;