diff options
Diffstat (limited to 'node_modules/montage/core/shim/weak-map.js')
-rwxr-xr-x | node_modules/montage/core/shim/weak-map.js | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/node_modules/montage/core/shim/weak-map.js b/node_modules/montage/core/shim/weak-map.js new file mode 100755 index 00000000..ae99a60c --- /dev/null +++ b/node_modules/montage/core/shim/weak-map.js | |||
@@ -0,0 +1,454 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> | ||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | ||
5 | </copyright> */ | ||
6 | /* <notice> | ||
7 | Derived from http://code.google.com/p/es-lab/source/browse/trunk/src/ses/WeakMap.js | ||
8 | Added the export | ||
9 | Removed the check for ses | ||
10 | // Copyright (C) 2011 Google Inc. | ||
11 | // | ||
12 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
13 | // you may not use this file except in compliance with the License. | ||
14 | // You may obtain a copy of the License at | ||
15 | // | ||
16 | // http://www.apache.org/licenses/LICENSE-2.0 | ||
17 | // | ||
18 | // Unless required by applicable law or agreed to in writing, software | ||
19 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
20 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
21 | // See the License for the specific language governing permissions and | ||
22 | // limitations under the License. | ||
23 | </notice> */ | ||
24 | |||
25 | /** | ||
26 | * @fileoverview Install a leaky WeakMap emulation on platforms that | ||
27 | * don't provide a built-in one. | ||
28 | * | ||
29 | * <p>Assumes that an ES5 platform where, if {@code WeakMap} is | ||
30 | * already present, then it conforms to the anticipated ES6 | ||
31 | * specification. To run this file on an ES5 or almost ES5 | ||
32 | * implementation where the {@code WeakMap} specification does not | ||
33 | * quite conform, run <code>repairES5.js</code> first. | ||
34 | * | ||
35 | * @author Mark S. Miller | ||
36 | * @requires ses | ||
37 | * @overrides WeakMap | ||
38 | */ | ||
39 | |||
40 | /** | ||
41 | @module montage/core/shim/weak-map | ||
42 | */ | ||
43 | |||
44 | /** | ||
45 | * This {@code WeakMap} emulation is observably equivalent to the | ||
46 | * ES-Harmony WeakMap, but with leakier garbage collection properties. | ||
47 | * | ||
48 | * As with true WeakMaps, in this emulation, a key does not | ||
49 | * retain maps indexed by that key and (crucially) a map does not | ||
50 | * retain the keys it indexes. A map by itself also does not retain | ||
51 | * the values associated with that map. | ||
52 | * | ||
53 | <p>However, the values associated with a key in some map are | ||
54 | * retained so long as that key is retained and those associations are | ||
55 | * not overridden. For example, when used to support membranes, all | ||
56 | * values exported from a given membrane will live for the lifetime | ||
57 | * they would have had in the absence of an interposed membrane. Even | ||
58 | * when the membrane is revoked, all objects that would have been | ||
59 | * reachable in the absence of revocation will still be reachable, as | ||
60 | * far as the GC can tell, even though they will no longer be relevant | ||
61 | * to ongoing computation. | ||
62 | * | ||
63 | * <p>The API implemented here is approximately the API as implemented | ||
64 | * in FF6.0a1 and agreed to by MarkM, Andreas Gal, and Dave Herman, | ||
65 | * rather than the offially approved proposal page. TODO(erights): | ||
66 | * upgrade the ecmascript WeakMap proposal page to explain this API | ||
67 | * change and present to EcmaScript committee for their approval. | ||
68 | * | ||
69 | <p>The first difference between the emulation here and that in | ||
70 | * FF6.0a1 is the presence of non enumerable {@code get___, has___, | ||
71 | * set___, and delete___} methods on WeakMap instances to represent | ||
72 | * what would be the hidden internal properties of a primitive | ||
73 | * implementation. Whereas the FF6.0a1 WeakMap.prototype methods | ||
74 | * require their {@code this} to be a genuine WeakMap instance (i.e., | ||
75 | * an object of {@code [[Class]]} "WeakMap}), since there is nothing | ||
76 | * unforgeable about the pseudo-internal method names used here, | ||
77 | * nothing prevents these emulated prototype methods from being | ||
78 | * applied to non-WeakMaps with pseudo-internal methods of the same | ||
79 | * names. | ||
80 | * | ||
81 | * <p>Another difference is that our emulated {@code | ||
82 | * WeakMap.prototype} is not itself a WeakMap. A problem with the | ||
83 | * current FF6.0a1 API is that WeakMap.prototype is itself a WeakMap | ||
84 | * providing ambient mutability and an ambient communications | ||
85 | * channel. Thus, if a WeakMap is already present and has this | ||
86 | * problem, repairES5.js wraps it in a safe wrappper in order to | ||
87 | * prevent access to this channel. (See | ||
88 | * PATCH_MUTABLE_FROZEN_WEAKMAP_PROTO in repairES5.js). | ||
89 | @class module:montage/core/shim/weak-map.WeakMap | ||
90 | */ | ||
91 | |||
92 | var WeakMap; | ||
93 | |||
94 | /** | ||
95 | * If this is a full <a href= | ||
96 | * "http://code.google.com/p/es-lab/wiki/SecureableES5" | ||
97 | * >secureable ES5</a> platform and the ES-Harmony {@code WeakMap} is | ||
98 | * absent, install an approximate emulation. | ||
99 | * | ||
100 | * <p>If this is almost a secureable ES5 platform, then WeakMap.js | ||
101 | * should be run after repairES5.js. | ||
102 | * | ||
103 | * <p>See {@code WeakMap} for documentation of the garbage collection | ||
104 | * properties of this WeakMap emulation. | ||
105 | */ | ||
106 | (function() { | ||
107 | "use strict"; | ||
108 | |||
109 | // if (typeof ses !== 'undefined' && ses.ok && !ses.ok()) { | ||
110 | // // already too broken, so give up | ||
111 | // return; | ||
112 | // } | ||
113 | |||
114 | if (typeof WeakMap === 'function') { | ||
115 | // assumed fine, so we're done. | ||
116 | return; | ||
117 | } | ||
118 | |||
119 | var hop = Object.prototype.hasOwnProperty; | ||
120 | var gopn = Object.getOwnPropertyNames; | ||
121 | var defProp = Object.defineProperty; | ||
122 | |||
123 | /** | ||
124 | * Holds the orginal static properties of the Object constructor, | ||
125 | * after repairES5 fixes these if necessary to be a more complete | ||
126 | * secureable ES5 environment, but before installing the following | ||
127 | * WeakMap emulation overrides and before any untrusted code runs. | ||
128 | */ | ||
129 | var originalProps = {}; | ||
130 | gopn(Object).forEach(function(name) { | ||
131 | originalProps[name] = Object[name]; | ||
132 | }); | ||
133 | |||
134 | /** | ||
135 | * Security depends on HIDDEN_NAME being both <i>unguessable</i> and | ||
136 | * <i>undiscoverable</i> by untrusted code. | ||
137 | * | ||
138 | * <p>Given the known weaknesses of Math.random() on existing | ||
139 | * browsers, it does not generate unguessability we can be confident | ||
140 | * of. TODO(erights): Detect crypto.getRandomValues and if there, | ||
141 | * use it instead. | ||
142 | * | ||
143 | * <p>It is the monkey patching logic in this file that is intended | ||
144 | * to ensure undiscoverability. The basic idea is that there are | ||
145 | * three fundamental means of discovering properties of an object: | ||
146 | * The for/in loop, Object.keys(), and Object.getOwnPropertyNames(), | ||
147 | * as well as some proposed ES6 extensions that appear on our | ||
148 | * whitelist. The first two only discover enumerable properties, and | ||
149 | * we only use HIDDEN_NAME to name a non-enumerable property, so the | ||
150 | * only remaining threat should be getOwnPropertyNames and some | ||
151 | * proposed ES6 extensions that appear on our whitelist. We monkey | ||
152 | * patch them to remove HIDDEN_NAME from the list of properties they | ||
153 | * returns. | ||
154 | */ | ||
155 | var HIDDEN_NAME = 'ident:' + Math.random() + '___'; | ||
156 | |||
157 | /** | ||
158 | * Monkey patch getOwnPropertyNames to avoid revealing the | ||
159 | * HIDDEN_NAME. | ||
160 | * | ||
161 | * <p>The ES5.1 spec requires each name to appear only once, but as | ||
162 | * of this writing, this requirement is controversial for ES6, so we | ||
163 | * made this code robust against this case. If the resulting extra | ||
164 | * search turns out to be expensive, we can probably relax this once | ||
165 | * ES6 is adequately supported on all major browsers, iff no browser | ||
166 | * versions we support at that time have relaxed this constraint | ||
167 | * without providing built-in ES6 WeakMaps. | ||
168 | */ | ||
169 | |||
170 | defProp(Object, 'getOwnPropertyNames', { | ||
171 | value: function fakeGetOwnPropertyNames(obj) { | ||
172 | var result = gopn(obj); | ||
173 | var i = 0; | ||
174 | while ((i = result.indexOf(HIDDEN_NAME, i)) >= 0) { | ||
175 | result.splice(i, 1); | ||
176 | } | ||
177 | return result; | ||
178 | } | ||
179 | }); | ||
180 | |||
181 | /** | ||
182 | getPropertyNames is not in ES5 but it is proposed for ES6 and<br> | ||
183 | does appear in our whitelist, so we need to clean it too. | ||
184 | */ | ||
185 | |||
186 | |||
187 | if ('getPropertyNames' in Object) { | ||
188 | defProp(Object, 'getPropertyNames', { | ||
189 | value: function fakeGetPropertyNames(obj) { | ||
190 | var result = originalProps.getPropertyNames(obj); | ||
191 | var i = 0; | ||
192 | while ((i = result.indexOf(HIDDEN_NAME, i)) >= 0) { | ||
193 | result.splice(i, 1); | ||
194 | } | ||
195 | return result; | ||
196 | } | ||
197 | }); | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * <p>To treat objects as identity-keys with reasonable efficiency | ||
202 | * on ES5 by itself (i.e., without any object-keyed collections), we | ||
203 | * need to add a hidden property to such key objects when we | ||
204 | * can. This raises several issues: | ||
205 | * <ul> | ||
206 | * <li>Arranging to add this property to objects before we lose the | ||
207 | * chance, and | ||
208 | * <li>Hiding the existence of this new property from most | ||
209 | * JavaScript code. | ||
210 | * <li>Preventing <i>certification theft</i>, where one object is | ||
211 | * created falsely claiming to be the key of an association | ||
212 | * actually keyed by another object. | ||
213 | * <li>Preventing <i>value theft</i>, where untrusted code with | ||
214 | * access to a key object but not a weak map nevertheless | ||
215 | * obtains access to the value associated with that key in that | ||
216 | * weak map. | ||
217 | * </ul> | ||
218 | * We do so by | ||
219 | * <ul> | ||
220 | * <li>Making the name of the hidden property unguessable, so "[]" | ||
221 | * inde |