OLD | NEW |
1 // Copyright 2006-2012 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 (function(global, utils) { | 5 (function(global, utils) { |
6 "use strict"; | 6 "use strict"; |
7 | 7 |
8 // ---------------------------------------------------------------------------- | 8 // ---------------------------------------------------------------------------- |
9 // Imports | 9 // Imports |
10 | 10 |
11 var GlobalArray = global.Array; | 11 var GlobalArray = global.Array; |
12 var IsNaN = global.isNaN; | 12 var IsNaN = global.isNaN; |
13 var JSONStringify = global.JSON.stringify; | 13 var JSONStringify = global.JSON.stringify; |
14 var GlobalMap = global.Map; | |
15 var MathMin = global.Math.min; | 14 var MathMin = global.Math.min; |
16 | 15 |
17 // ---------------------------------------------------------------------------- | 16 // ---------------------------------------------------------------------------- |
18 | 17 |
19 // Mirror hierarchy: | 18 // Mirror hierarchy: |
20 // - Mirror | 19 // - Mirror |
21 // - ValueMirror | 20 // - ValueMirror |
22 // - UndefinedMirror | 21 // - UndefinedMirror |
23 // - NullMirror | 22 // - NullMirror |
24 // - BooleanMirror | 23 // - BooleanMirror |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 ITERATOR_TYPE : 'iterator', | 66 ITERATOR_TYPE : 'iterator', |
68 GENERATOR_TYPE : 'generator', | 67 GENERATOR_TYPE : 'generator', |
69 } | 68 } |
70 | 69 |
71 | 70 |
72 // Handle id counters. | 71 // Handle id counters. |
73 var next_handle_ = 0; | 72 var next_handle_ = 0; |
74 var next_transient_handle_ = -1; | 73 var next_transient_handle_ = -1; |
75 | 74 |
76 // Mirror cache. | 75 // Mirror cache. |
77 var mirror_cache_ = new GlobalMap(); | 76 var mirror_cache_ = []; |
78 var mirror_cache_enabled_ = true; | 77 var mirror_cache_enabled_ = true; |
79 | 78 |
80 | 79 |
81 function MirrorCacheIsEmpty() { | 80 function MirrorCacheIsEmpty() { |
82 return mirror_cache_.size === 0; | 81 return next_handle_ == 0 && mirror_cache_.length == 0; |
83 } | 82 } |
84 | 83 |
85 | 84 |
86 function ToggleMirrorCache(value) { | 85 function ToggleMirrorCache(value) { |
87 mirror_cache_enabled_ = value; | 86 mirror_cache_enabled_ = value; |
88 ClearMirrorCache(); | 87 ClearMirrorCache(); |
89 } | 88 } |
90 | 89 |
91 | 90 |
92 function ClearMirrorCache(value) { | 91 function ClearMirrorCache(value) { |
93 next_handle_ = 0; | 92 next_handle_ = 0; |
94 mirror_cache_.clear(); | 93 mirror_cache_ = []; |
95 } | 94 } |
96 | 95 |
97 | 96 |
98 // Wrapper to check whether an object is a Promise. The call may not work | 97 // Wrapper to check whether an object is a Promise. The call may not work |
99 // if promises are not enabled. | 98 // if promises are not enabled. |
100 // TODO(yangguo): remove try-catch once promises are enabled by default. | 99 // TODO(yangguo): remove try-catch once promises are enabled by default. |
101 function ObjectIsPromise(value) { | 100 function ObjectIsPromise(value) { |
102 try { | 101 try { |
103 return IS_SPEC_OBJECT(value) && | 102 return IS_SPEC_OBJECT(value) && |
104 !IS_UNDEFINED(%DebugGetProperty(value, builtins.$promiseStatus)); | 103 !IS_UNDEFINED(%DebugGetProperty(value, builtins.$promiseStatus)); |
105 } catch (e) { | 104 } catch (e) { |
106 return false; | 105 return false; |
107 } | 106 } |
108 } | 107 } |
109 | 108 |
110 | 109 |
111 /** | 110 /** |
112 * Returns the mirror for a specified value or object. | 111 * Returns the mirror for a specified value or object. |
113 * | 112 * |
114 * @param {value or Object} value the value or object to retreive the mirror for | 113 * @param {value or Object} value the value or object to retreive the mirror for |
115 * @param {boolean} transient indicate whether this object is transient and | 114 * @param {boolean} transient indicate whether this object is transient and |
116 * should not be added to the mirror cache. The default is not transient. | 115 * should not be added to the mirror cache. The default is not transient. |
117 * @returns {Mirror} the mirror reflects the passed value or object | 116 * @returns {Mirror} the mirror reflects the passed value or object |
118 */ | 117 */ |
119 function MakeMirror(value, opt_transient) { | 118 function MakeMirror(value, opt_transient) { |
120 var mirror; | 119 var mirror; |
121 | 120 |
122 // Look for non transient mirrors in the mirror cache. | 121 // Look for non transient mirrors in the mirror cache. |
123 if (!opt_transient && mirror_cache_enabled_) { | 122 if (!opt_transient && mirror_cache_enabled_) { |
124 if (mirror_cache_.has(value)) return mirror_cache_.get(value); | 123 for (var id in mirror_cache_) { |
| 124 mirror = mirror_cache_[id]; |
| 125 if (mirror.value() === value) { |
| 126 return mirror; |
| 127 } |
| 128 // Special check for NaN as NaN == NaN is false. |
| 129 if (mirror.isNumber() && IsNaN(mirror.value()) && |
| 130 typeof value == 'number' && IsNaN(value)) { |
| 131 return mirror; |
| 132 } |
| 133 } |
125 } | 134 } |
126 | 135 |
127 if (IS_UNDEFINED(value)) { | 136 if (IS_UNDEFINED(value)) { |
128 mirror = new UndefinedMirror(); | 137 mirror = new UndefinedMirror(); |
129 } else if (IS_NULL(value)) { | 138 } else if (IS_NULL(value)) { |
130 mirror = new NullMirror(); | 139 mirror = new NullMirror(); |
131 } else if (IS_BOOLEAN(value)) { | 140 } else if (IS_BOOLEAN(value)) { |
132 mirror = new BooleanMirror(value); | 141 mirror = new BooleanMirror(value); |
133 } else if (IS_NUMBER(value)) { | 142 } else if (IS_NUMBER(value)) { |
134 mirror = new NumberMirror(value); | 143 mirror = new NumberMirror(value); |
(...skipping 20 matching lines...) Expand all Loading... |
155 } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) { | 164 } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) { |
156 mirror = new IteratorMirror(value); | 165 mirror = new IteratorMirror(value); |
157 } else if (ObjectIsPromise(value)) { | 166 } else if (ObjectIsPromise(value)) { |
158 mirror = new PromiseMirror(value); | 167 mirror = new PromiseMirror(value); |
159 } else if (IS_GENERATOR(value)) { | 168 } else if (IS_GENERATOR(value)) { |
160 mirror = new GeneratorMirror(value); | 169 mirror = new GeneratorMirror(value); |
161 } else { | 170 } else { |
162 mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE, opt_transient); | 171 mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE, opt_transient); |
163 } | 172 } |
164 | 173 |
165 if (mirror_cache_enabled_) mirror_cache_.set(value, mirror); | 174 if (mirror_cache_enabled_) mirror_cache_[mirror.handle()] = mirror; |
166 return mirror; | 175 return mirror; |
167 } | 176 } |
168 | 177 |
169 | 178 |
170 /** | 179 /** |
171 * Returns the mirror for a specified mirror handle. | 180 * Returns the mirror for a specified mirror handle. |
172 * | 181 * |
173 * @param {number} handle the handle to find the mirror for | 182 * @param {number} handle the handle to find the mirror for |
174 * @returns {Mirror or undefiend} the mirror with the requested handle or | 183 * @returns {Mirror or undefiend} the mirror with the requested handle or |
175 * undefined if no mirror with the requested handle was found | 184 * undefined if no mirror with the requested handle was found |
176 */ | 185 */ |
177 function LookupMirror(handle) { | 186 function LookupMirror(handle) { |
178 if (!mirror_cache_enabled_) { | 187 if (!mirror_cache_enabled_) { |
179 throw MakeError(kDebugger, "Mirror cache is disabled"); | 188 throw MakeError(kDebugger, "Mirror cache is disabled"); |
180 } | 189 } |
181 for (var value of mirror_cache_.values()) { | 190 return mirror_cache_[handle]; |
182 if (value.handle() == handle) return value; | |
183 } | |
184 return UNDEFINED; | |
185 } | 191 } |
186 | 192 |
187 | 193 |
188 /** | 194 /** |
189 * Returns the mirror for the undefined value. | 195 * Returns the mirror for the undefined value. |
190 * | 196 * |
191 * @returns {Mirror} the mirror reflects the undefined value | 197 * @returns {Mirror} the mirror reflects the undefined value |
192 */ | 198 */ |
193 function GetUndefinedMirror() { | 199 function GetUndefinedMirror() { |
194 return MakeMirror(UNDEFINED); | 200 return MakeMirror(UNDEFINED); |
(...skipping 2897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3092 // Functions needed by the debugger runtime. | 3098 // Functions needed by the debugger runtime. |
3093 utils.InstallFunctions(utils, DONT_ENUM, [ | 3099 utils.InstallFunctions(utils, DONT_ENUM, [ |
3094 "ClearMirrorCache", ClearMirrorCache | 3100 "ClearMirrorCache", ClearMirrorCache |
3095 ]); | 3101 ]); |
3096 | 3102 |
3097 // Export to debug.js | 3103 // Export to debug.js |
3098 utils.Export(function(to) { | 3104 utils.Export(function(to) { |
3099 to.MirrorType = MirrorType; | 3105 to.MirrorType = MirrorType; |
3100 }); | 3106 }); |
3101 }) | 3107 }) |
OLD | NEW |