aboutsummaryrefslogtreecommitdiff
path: root/node_modules/montage/core/shim/weak-map.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/montage/core/shim/weak-map.js')
-rwxr-xr-xnode_modules/montage/core/shim/weak-map.js454
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
92var 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 * indexing, which we cannot intercept, cannot be used to access
222 * a property without knowing the name.
223 * <li>Making the hidden property non-enumerable, so we need not