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 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 SCRIPT_TYPE : 'script', | 70 SCRIPT_TYPE : 'script', |
71 CONTEXT_TYPE : 'context', | 71 CONTEXT_TYPE : 'context', |
72 SCOPE_TYPE : 'scope', | 72 SCOPE_TYPE : 'scope', |
73 PROMISE_TYPE : 'promise', | 73 PROMISE_TYPE : 'promise', |
74 MAP_TYPE : 'map', | 74 MAP_TYPE : 'map', |
75 SET_TYPE : 'set', | 75 SET_TYPE : 'set', |
76 ITERATOR_TYPE : 'iterator', | 76 ITERATOR_TYPE : 'iterator', |
77 GENERATOR_TYPE : 'generator', | 77 GENERATOR_TYPE : 'generator', |
78 } | 78 } |
79 | 79 |
80 | |
81 // Handle id counters. | |
82 var next_handle_ = 0; | |
83 var next_transient_handle_ = -1; | |
84 | |
85 // Mirror cache. | |
86 var mirror_cache_ = []; | |
87 var mirror_cache_enabled_ = true; | |
88 | |
89 | |
90 function MirrorCacheIsEmpty() { | |
91 return next_handle_ == 0 && mirror_cache_.length == 0; | |
92 } | |
93 | |
94 | |
95 function ToggleMirrorCache(value) { | |
96 mirror_cache_enabled_ = value; | |
97 ClearMirrorCache(); | |
98 } | |
99 | |
100 | |
101 function ClearMirrorCache(value) { | |
102 next_handle_ = 0; | |
103 mirror_cache_ = []; | |
104 } | |
105 | |
106 | |
107 /** | 80 /** |
108 * Returns the mirror for a specified value or object. | 81 * Returns the mirror for a specified value or object. |
109 * | 82 * |
110 * @param {value or Object} value the value or object to retrieve the mirror for | 83 * @param {value or Object} value the value or object to retrieve the mirror for |
111 * @param {boolean} transient indicate whether this object is transient and | |
112 * should not be added to the mirror cache. The default is not transient. | |
113 * @returns {Mirror} the mirror reflects the passed value or object | 84 * @returns {Mirror} the mirror reflects the passed value or object |
114 */ | 85 */ |
115 function MakeMirror(value, opt_transient) { | 86 function MakeMirror(value) { |
116 var mirror; | 87 var mirror; |
117 | 88 |
118 // Look for non transient mirrors in the mirror cache. | |
119 if (!opt_transient && mirror_cache_enabled_) { | |
120 for (var id in mirror_cache_) { | |
121 mirror = mirror_cache_[id]; | |
122 if (mirror.value() === value) { | |
123 return mirror; | |
124 } | |
125 // Special check for NaN as NaN == NaN is false. | |
126 if (mirror.isNumber() && IsNaN(mirror.value()) && | |
127 typeof value == 'number' && IsNaN(value)) { | |
128 return mirror; | |
129 } | |
130 } | |
131 } | |
132 | |
133 if (IS_UNDEFINED(value)) { | 89 if (IS_UNDEFINED(value)) { |
134 mirror = new UndefinedMirror(); | 90 mirror = new UndefinedMirror(); |
135 } else if (IS_NULL(value)) { | 91 } else if (IS_NULL(value)) { |
136 mirror = new NullMirror(); | 92 mirror = new NullMirror(); |
137 } else if (IS_BOOLEAN(value)) { | 93 } else if (IS_BOOLEAN(value)) { |
138 mirror = new BooleanMirror(value); | 94 mirror = new BooleanMirror(value); |
139 } else if (IS_NUMBER(value)) { | 95 } else if (IS_NUMBER(value)) { |
140 mirror = new NumberMirror(value); | 96 mirror = new NumberMirror(value); |
141 } else if (IS_STRING(value)) { | 97 } else if (IS_STRING(value)) { |
142 mirror = new StringMirror(value); | 98 mirror = new StringMirror(value); |
(...skipping 15 matching lines...) Expand all Loading... |
158 mirror = new MapMirror(value); | 114 mirror = new MapMirror(value); |
159 } else if (IS_SET(value) || IS_WEAKSET(value)) { | 115 } else if (IS_SET(value) || IS_WEAKSET(value)) { |
160 mirror = new SetMirror(value); | 116 mirror = new SetMirror(value); |
161 } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) { | 117 } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) { |
162 mirror = new IteratorMirror(value); | 118 mirror = new IteratorMirror(value); |
163 } else if (%is_promise(value)) { | 119 } else if (%is_promise(value)) { |
164 mirror = new PromiseMirror(value); | 120 mirror = new PromiseMirror(value); |
165 } else if (IS_GENERATOR(value)) { | 121 } else if (IS_GENERATOR(value)) { |
166 mirror = new GeneratorMirror(value); | 122 mirror = new GeneratorMirror(value); |
167 } else { | 123 } else { |
168 mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE, opt_transient); | 124 mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE); |
169 } | 125 } |
170 | 126 |
171 if (mirror_cache_enabled_) mirror_cache_[mirror.handle()] = mirror; | |
172 return mirror; | 127 return mirror; |
173 } | 128 } |
174 | 129 |
175 | 130 |
176 /** | 131 /** |
177 * Returns the mirror for a specified mirror handle. | |
178 * | |
179 * @param {number} handle the handle to find the mirror for | |
180 * @returns {Mirror or undefiend} the mirror with the requested handle or | |
181 * undefined if no mirror with the requested handle was found | |
182 */ | |
183 function LookupMirror(handle) { | |
184 if (!mirror_cache_enabled_) { | |
185 throw %make_error(kDebugger, "Mirror cache is disabled"); | |
186 } | |
187 return mirror_cache_[handle]; | |
188 } | |
189 | |
190 | |
191 /** | |
192 * Returns the mirror for the undefined value. | 132 * Returns the mirror for the undefined value. |
193 * | 133 * |
194 * @returns {Mirror} the mirror reflects the undefined value | 134 * @returns {Mirror} the mirror reflects the undefined value |
195 */ | 135 */ |
196 function GetUndefinedMirror() { | 136 function GetUndefinedMirror() { |
197 return MakeMirror(UNDEFINED); | 137 return MakeMirror(UNDEFINED); |
198 } | 138 } |
199 | 139 |
200 | 140 |
201 /** | 141 /** |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 | 424 |
485 /** | 425 /** |
486 * Check whether the mirror reflects an iterator. | 426 * Check whether the mirror reflects an iterator. |
487 * @returns {boolean} True if the mirror reflects an iterator | 427 * @returns {boolean} True if the mirror reflects an iterator |
488 */ | 428 */ |
489 Mirror.prototype.isIterator = function() { | 429 Mirror.prototype.isIterator = function() { |
490 return this instanceof IteratorMirror; | 430 return this instanceof IteratorMirror; |
491 }; | 431 }; |
492 | 432 |
493 | 433 |
494 /** | |
495 * Allocate a handle id for this object. | |
496 */ | |
497 Mirror.prototype.allocateHandle_ = function() { | |
498 if (mirror_cache_enabled_) this.handle_ = next_handle_++; | |
499 }; | |
500 | |
501 | |
502 /** | |
503 * Allocate a transient handle id for this object. Transient handles are | |
504 * negative. | |
505 */ | |
506 Mirror.prototype.allocateTransientHandle_ = function() { | |
507 this.handle_ = next_transient_handle_--; | |
508 }; | |
509 | |
510 | |
511 Mirror.prototype.toText = function() { | 434 Mirror.prototype.toText = function() { |
512 // Simpel to text which is used when on specialization in subclass. | 435 // Simpel to text which is used when on specialization in subclass. |
513 return "#<" + this.constructor.name + ">"; | 436 return "#<" + this.constructor.name + ">"; |
514 }; | 437 }; |
515 | 438 |
516 | 439 |
517 /** | 440 /** |
518 * Base class for all value mirror objects. | 441 * Base class for all value mirror objects. |
519 * @param {string} type The type of the mirror | 442 * @param {string} type The type of the mirror |
520 * @param {value} value The value reflected by this mirror | 443 * @param {value} value The value reflected by this mirror |
521 * @param {boolean} transient indicate whether this object is transient with a | |
522 * transient handle | |
523 * @constructor | 444 * @constructor |
524 * @extends Mirror | 445 * @extends Mirror |
525 */ | 446 */ |
526 function ValueMirror(type, value, transient) { | 447 function ValueMirror(type, value) { |
527 %_Call(Mirror, this, type); | 448 %_Call(Mirror, this, type); |
528 this.value_ = value; | 449 this.value_ = value; |
529 if (!transient) { | |
530 this.allocateHandle_(); | |
531 } else { | |
532 this.allocateTransientHandle_(); | |
533 } | |
534 } | 450 } |
535 inherits(ValueMirror, Mirror); | 451 inherits(ValueMirror, Mirror); |
536 | 452 |
537 | 453 |
538 Mirror.prototype.handle = function() { | |
539 return this.handle_; | |
540 }; | |
541 | |
542 | |
543 /** | 454 /** |
544 * Check whether this is a primitive value. | 455 * Check whether this is a primitive value. |
545 * @return {boolean} True if the mirror reflects a primitive value | 456 * @return {boolean} True if the mirror reflects a primitive value |
546 */ | 457 */ |
547 ValueMirror.prototype.isPrimitive = function() { | 458 ValueMirror.prototype.isPrimitive = function() { |
548 var type = this.type(); | 459 var type = this.type(); |
549 return type === 'undefined' || | 460 return type === 'undefined' || |
550 type === 'null' || | 461 type === 'null' || |
551 type === 'boolean' || | 462 type === 'boolean' || |
552 type === 'number' || | 463 type === 'number' || |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 | 588 |
678 | 589 |
679 SymbolMirror.prototype.toText = function() { | 590 SymbolMirror.prototype.toText = function() { |
680 return %SymbolDescriptiveString(%ValueOf(this.value_)); | 591 return %SymbolDescriptiveString(%ValueOf(this.value_)); |
681 } | 592 } |
682 | 593 |
683 | 594 |
684 /** | 595 /** |
685 * Mirror object for objects. | 596 * Mirror object for objects. |
686 * @param {object} value The object reflected by this mirror | 597 * @param {object} value The object reflected by this mirror |
687 * @param {boolean} transient indicate whether this object is transient with a | |
688 * transient handle | |
689 * @constructor | 598 * @constructor |
690 * @extends ValueMirror | 599 * @extends ValueMirror |
691 */ | 600 */ |
692 function ObjectMirror(value, type, transient) { | 601 function ObjectMirror(value, type) { |
693 type = type || MirrorType.OBJECT_TYPE; | 602 type = type || MirrorType.OBJECT_TYPE; |
694 %_Call(ValueMirror, this, type, value, transient); | 603 %_Call(ValueMirror, this, type, value); |
695 } | 604 } |
696 inherits(ObjectMirror, ValueMirror); | 605 inherits(ObjectMirror, ValueMirror); |
697 | 606 |
698 | 607 |
699 ObjectMirror.prototype.className = function() { | 608 ObjectMirror.prototype.className = function() { |
700 return %_ClassOf(this.value_); | 609 return %_ClassOf(this.value_); |
701 }; | 610 }; |
702 | 611 |
703 | 612 |
704 ObjectMirror.prototype.constructorFunction = function() { | 613 ObjectMirror.prototype.constructorFunction = function() { |
(...skipping 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2306 return this.scope_index_; | 2215 return this.scope_index_; |
2307 }; | 2216 }; |
2308 | 2217 |
2309 | 2218 |
2310 ScopeMirror.prototype.scopeType = function() { | 2219 ScopeMirror.prototype.scopeType = function() { |
2311 return this.details_.type(); | 2220 return this.details_.type(); |
2312 }; | 2221 }; |
2313 | 2222 |
2314 | 2223 |
2315 ScopeMirror.prototype.scopeObject = function() { | 2224 ScopeMirror.prototype.scopeObject = function() { |
2316 // For local, closure and script scopes create a transient mirror | 2225 // For local, closure and script scopes create a mirror |
2317 // as these objects are created on the fly materializing the local | 2226 // as these objects are created on the fly materializing the local |
2318 // or closure scopes and therefore will not preserve identity. | 2227 // or closure scopes and therefore will not preserve identity. |
2319 var transient = this.scopeType() == ScopeType.Local || | 2228 return MakeMirror(this.details_.object()); |
2320 this.scopeType() == ScopeType.Closure || | |
2321 this.scopeType() == ScopeType.Script; | |
2322 return MakeMirror(this.details_.object(), transient); | |
2323 }; | 2229 }; |
2324 | 2230 |
2325 | 2231 |
2326 ScopeMirror.prototype.setVariableValue = function(name, new_value) { | 2232 ScopeMirror.prototype.setVariableValue = function(name, new_value) { |
2327 this.details_.setVariableValueImpl(name, new_value); | 2233 this.details_.setVariableValueImpl(name, new_value); |
2328 }; | 2234 }; |
2329 | 2235 |
2330 | 2236 |
2331 /** | 2237 /** |
2332 * Mirror object for script source. | 2238 * Mirror object for script source. |
2333 * @param {Script} script The script object | 2239 * @param {Script} script The script object |
2334 * @constructor | 2240 * @constructor |
2335 * @extends Mirror | 2241 * @extends Mirror |
2336 */ | 2242 */ |
2337 function ScriptMirror(script) { | 2243 function ScriptMirror(script) { |
2338 %_Call(Mirror, this, MirrorType.SCRIPT_TYPE); | 2244 %_Call(Mirror, this, MirrorType.SCRIPT_TYPE); |
2339 this.script_ = script; | 2245 this.script_ = script; |
2340 this.context_ = new ContextMirror(script.context_data); | 2246 this.context_ = new ContextMirror(script.context_data); |
2341 this.allocateHandle_(); | |
2342 } | 2247 } |
2343 inherits(ScriptMirror, Mirror); | 2248 inherits(ScriptMirror, Mirror); |
2344 | 2249 |
2345 | 2250 |
2346 ScriptMirror.prototype.value = function() { | 2251 ScriptMirror.prototype.value = function() { |
2347 return this.script_; | 2252 return this.script_; |
2348 }; | 2253 }; |
2349 | 2254 |
2350 | 2255 |
2351 ScriptMirror.prototype.name = function() { | 2256 ScriptMirror.prototype.name = function() { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2447 | 2352 |
2448 /** | 2353 /** |
2449 * Mirror object for context. | 2354 * Mirror object for context. |
2450 * @param {Object} data The context data | 2355 * @param {Object} data The context data |
2451 * @constructor | 2356 * @constructor |
2452 * @extends Mirror | 2357 * @extends Mirror |
2453 */ | 2358 */ |
2454 function ContextMirror(data) { | 2359 function ContextMirror(data) { |
2455 %_Call(Mirror, this, MirrorType.CONTEXT_TYPE); | 2360 %_Call(Mirror, this, MirrorType.CONTEXT_TYPE); |
2456 this.data_ = data; | 2361 this.data_ = data; |
2457 this.allocateHandle_(); | |
2458 } | 2362 } |
2459 inherits(ContextMirror, Mirror); | 2363 inherits(ContextMirror, Mirror); |
2460 | 2364 |
2461 | 2365 |
2462 ContextMirror.prototype.data = function() { | 2366 ContextMirror.prototype.data = function() { |
2463 return this.data_; | 2367 return this.data_; |
2464 }; | 2368 }; |
2465 | 2369 |
2466 // ---------------------------------------------------------------------------- | 2370 // ---------------------------------------------------------------------------- |
2467 // Exports | 2371 // Exports |
2468 | 2372 |
2469 utils.InstallFunctions(global, DONT_ENUM, [ | 2373 utils.InstallFunctions(global, DONT_ENUM, [ |
2470 "MakeMirror", MakeMirror, | 2374 "MakeMirror", MakeMirror, |
2471 "LookupMirror", LookupMirror, | |
2472 "ToggleMirrorCache", ToggleMirrorCache, | |
2473 "MirrorCacheIsEmpty", MirrorCacheIsEmpty, | |
2474 ]); | 2375 ]); |
2475 | 2376 |
2476 utils.InstallConstants(global, [ | 2377 utils.InstallConstants(global, [ |
2477 "ScopeType", ScopeType, | 2378 "ScopeType", ScopeType, |
2478 "PropertyType", PropertyType, | 2379 "PropertyType", PropertyType, |
2479 "PropertyAttribute", PropertyAttribute, | 2380 "PropertyAttribute", PropertyAttribute, |
2480 "Mirror", Mirror, | 2381 "Mirror", Mirror, |
2481 "ValueMirror", ValueMirror, | 2382 "ValueMirror", ValueMirror, |
2482 "UndefinedMirror", UndefinedMirror, | 2383 "UndefinedMirror", UndefinedMirror, |
2483 "NullMirror", NullMirror, | 2384 "NullMirror", NullMirror, |
(...skipping 14 matching lines...) Expand all Loading... |
2498 "IteratorMirror", IteratorMirror, | 2399 "IteratorMirror", IteratorMirror, |
2499 "GeneratorMirror", GeneratorMirror, | 2400 "GeneratorMirror", GeneratorMirror, |
2500 "PropertyMirror", PropertyMirror, | 2401 "PropertyMirror", PropertyMirror, |
2501 "InternalPropertyMirror", InternalPropertyMirror, | 2402 "InternalPropertyMirror", InternalPropertyMirror, |
2502 "FrameMirror", FrameMirror, | 2403 "FrameMirror", FrameMirror, |
2503 "ScriptMirror", ScriptMirror, | 2404 "ScriptMirror", ScriptMirror, |
2504 "ScopeMirror", ScopeMirror, | 2405 "ScopeMirror", ScopeMirror, |
2505 "FrameDetails", FrameDetails, | 2406 "FrameDetails", FrameDetails, |
2506 ]); | 2407 ]); |
2507 | 2408 |
2508 // Functions needed by the debugger runtime. | |
2509 utils.InstallFunctions(utils, DONT_ENUM, [ | |
2510 "ClearMirrorCache", ClearMirrorCache | |
2511 ]); | |
2512 | |
2513 // Export to debug.js | 2409 // Export to debug.js |
2514 utils.Export(function(to) { | 2410 utils.Export(function(to) { |
2515 to.MirrorType = MirrorType; | 2411 to.MirrorType = MirrorType; |
2516 }); | 2412 }); |
2517 }) | 2413 }) |
OLD | NEW |