| 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 |