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
3 // found in the LICENSE file.
5 (function(global, utils) {
8 // ----------------------------------------------------------------------------
11 var FunctionSourceString;
12 var GlobalArray = global.Array;
13 var IsNaN = global.isNaN;
14 var JSONStringify = global.JSON.stringify;
15 var MathMin = global.Math.min;
16 var promiseStatusSymbol = utils.GetPrivateSymbol("promise_status_symbol");
17 var promiseValueSymbol = utils.GetPrivateSymbol("promise_value_symbol");
21 utils.Import(function(from) {
22 FunctionSourceString = from.FunctionSourceString;
23 ToBoolean = from.ToBoolean;
24 ToString = from.ToString;
27 // ----------------------------------------------------------------------------
40 // - UnresolvedFunctionMirror
51 // - InternalPropertyMirror
56 // Type names of the different mirrors.
58 UNDEFINED_TYPE : 'undefined',
60 BOOLEAN_TYPE : 'boolean',
61 NUMBER_TYPE : 'number',
62 STRING_TYPE : 'string',
63 SYMBOL_TYPE : 'symbol',
64 OBJECT_TYPE : 'object',
65 FUNCTION_TYPE : 'function',
66 REGEXP_TYPE : 'regexp',
68 PROPERTY_TYPE : 'property',
69 INTERNAL_PROPERTY_TYPE : 'internalProperty',
71 SCRIPT_TYPE : 'script',
72 CONTEXT_TYPE : 'context',
74 PROMISE_TYPE : 'promise',
77 ITERATOR_TYPE : 'iterator',
78 GENERATOR_TYPE : 'generator',
82 // Handle id counters.
84 var next_transient_handle_ = -1;
87 var mirror_cache_ = [];
88 var mirror_cache_enabled_ = true;
91 function MirrorCacheIsEmpty() {
92 return next_handle_ == 0 && mirror_cache_.length == 0;
96 function ToggleMirrorCache(value) {
97 mirror_cache_enabled_ = value;
102 function ClearMirrorCache(value) {
108 // Wrapper to check whether an object is a Promise. The call may not work
109 // if promises are not enabled.
110 // TODO(yangguo): remove try-catch once promises are enabled by default.
111 function ObjectIsPromise(value) {
113 return IS_SPEC_OBJECT(value) &&
114 !IS_UNDEFINED(%DebugGetProperty(value, promiseStatusSymbol));
122 * Returns the mirror for a specified value or object.
124 * @param {value or Object} value the value or object to retreive the mirror for
125 * @param {boolean} transient indicate whether this object is transient and
126 * should not be added to the mirror cache. The default is not transient.
127 * @returns {Mirror} the mirror reflects the passed value or object
129 function MakeMirror(value, opt_transient) {
132 // Look for non transient mirrors in the mirror cache.
133 if (!opt_transient && mirror_cache_enabled_) {
134 for (var id in mirror_cache_) {
135 mirror = mirror_cache_[id];
136 if (mirror.value() === value) {
139 // Special check for NaN as NaN == NaN is false.
140 if (mirror.isNumber() && IsNaN(mirror.value()) &&
141 typeof value == 'number' && IsNaN(value)) {
147 if (IS_UNDEFINED(value)) {
148 mirror = new UndefinedMirror();
149 } else if (IS_NULL(value)) {
150 mirror = new NullMirror();
151 } else if (IS_BOOLEAN(value)) {
152 mirror = new BooleanMirror(value);
153 } else if (IS_NUMBER(value)) {
154 mirror = new NumberMirror(value);
155 } else if (IS_STRING(value)) {
156 mirror = new StringMirror(value);
157 } else if (IS_SYMBOL(value)) {
158 mirror = new SymbolMirror(value);
159 } else if (IS_ARRAY(value)) {
160 mirror = new ArrayMirror(value);
161 } else if (IS_DATE(value)) {
162 mirror = new DateMirror(value);
163 } else if (IS_FUNCTION(value)) {
164 mirror = new FunctionMirror(value);
165 } else if (IS_REGEXP(value)) {
166 mirror = new RegExpMirror(value);
167 } else if (IS_ERROR(value)) {
168 mirror = new ErrorMirror(value);
169 } else if (IS_SCRIPT(value)) {
170 mirror = new ScriptMirror(value);
171 } else if (IS_MAP(value) || IS_WEAKMAP(value)) {
172 mirror = new MapMirror(value);
173 } else if (IS_SET(value) || IS_WEAKSET(value)) {
174 mirror = new SetMirror(value);
175 } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) {
176 mirror = new IteratorMirror(value);
177 } else if (ObjectIsPromise(value)) {
178 mirror = new PromiseMirror(value);
179 } else if (IS_GENERATOR(value)) {
180 mirror = new GeneratorMirror(value);
182 mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE, opt_transient);
185 if (mirror_cache_enabled_) mirror_cache_[mirror.handle()] = mirror;
191 * Returns the mirror for a specified mirror handle.
193 * @param {number} handle the handle to find the mirror for
194 * @returns {Mirror or undefiend} the mirror with the requested handle or
195 * undefined if no mirror with the requested handle was found
197 function LookupMirror(handle) {
198 if (!mirror_cache_enabled_) {
199 throw MakeError(kDebugger, "Mirror cache is disabled");
201 return mirror_cache_[handle];
206 * Returns the mirror for the undefined value.
208 * @returns {Mirror} the mirror reflects the undefined value
210 function GetUndefinedMirror() {
211 return MakeMirror(UNDEFINED);
216 * Inherit the prototype methods from one constructor into another.
218 * The Function.prototype.inherits from lang.js rewritten as a standalone
219 * function (not on Function.prototype). NOTE: If this file is to be loaded
220 * during bootstrapping this function needs to be revritten using some native
221 * functions as prototype setup using normal JavaScript does not work as
222 * expected during bootstrapping (see mirror.js in r114903).
224 * @param {function} ctor Constructor function which needs to inherit the
226 * @param {function} superCtor Constructor function to inherit prototype from
228 function inherits(ctor, superCtor) {
229 var tempCtor = function(){};
230 tempCtor.prototype = superCtor.prototype;
231 ctor.super_ = superCtor.prototype;
232 ctor.prototype = new tempCtor();
233 ctor.prototype.constructor = ctor;
236 // Maximum length when sending strings through the JSON protocol.
237 var kMaxProtocolStringLength = 80;
239 // Different kind of properties.
240 var PropertyKind = {};
241 PropertyKind.Named = 1;
242 PropertyKind.Indexed = 2;
245 // A copy of the PropertyType enum from property-details.h
246 var PropertyType = {};
247 PropertyType.Data = 0;
248 PropertyType.DataConstant = 2;
249 PropertyType.AccessorConstant = 3;
252 // Different attributes for a property.
253 var PropertyAttribute = {};
254 PropertyAttribute.None = NONE;
255 PropertyAttribute.ReadOnly = READ_ONLY;
256 PropertyAttribute.DontEnum = DONT_ENUM;
257 PropertyAttribute.DontDelete = DONT_DELETE;
260 // A copy of the scope types from runtime-debug.cc.
261 // NOTE: these constants should be backward-compatible, so
262 // add new ones to the end of this list.
263 var ScopeType = { Global: 0,
272 * Base class for all mirror objects.
273 * @param {string} type The type of the mirror
276 function Mirror(type) {
281 Mirror.prototype.type = function() {
287 * Check whether the mirror reflects a value.
288 * @returns {boolean} True if the mirror reflects a value.
290 Mirror.prototype.isValue = function() {
291 return this instanceof ValueMirror;
296 * Check whether the mirror reflects the undefined value.
297 * @returns {boolean} True if the mirror reflects the undefined value.
299 Mirror.prototype.isUndefined = function() {
300 return this instanceof UndefinedMirror;
305 * Check whether the mirror reflects the null value.
306 * @returns {boolean} True if the mirror reflects the null value
308 Mirror.prototype.isNull = function() {
309 return this instanceof NullMirror;
314 * Check whether the mirror reflects a boolean value.
315 * @returns {boolean} True if the mirror reflects a boolean value
317 Mirror.prototype.isBoolean = function() {
318 return this instanceof BooleanMirror;
323 * Check whether the mirror reflects a number value.
324 * @returns {boolean} True if the mirror reflects a number value
326 Mirror.prototype.isNumber = function() {
327 return this instanceof NumberMirror;
332 * Check whether the mirror reflects a string value.
333 * @returns {boolean} True if the mirror reflects a string value
335 Mirror.prototype.isString = function() {
336 return this instanceof StringMirror;
341 * Check whether the mirror reflects a symbol.
342 * @returns {boolean} True if the mirror reflects a symbol
344 Mirror.prototype.isSymbol = function() {
345 return this instanceof SymbolMirror;
350 * Check whether the mirror reflects an object.
351 * @returns {boolean} True if the mirror reflects an object
353 Mirror.prototype.isObject = function() {
354 return this instanceof ObjectMirror;
359 * Check whether the mirror reflects a function.
360 * @returns {boolean} True if the mirror reflects a function
362 Mirror.prototype.isFunction = function() {
363 return this instanceof FunctionMirror;
368 * Check whether the mirror reflects an unresolved function.
369 * @returns {boolean} True if the mirror reflects an unresolved function
371 Mirror.prototype.isUnresolvedFunction = function() {
372 return this instanceof UnresolvedFunctionMirror;
377 * Check whether the mirror reflects an array.
378 * @returns {boolean} True if the mirror reflects an array
380 Mirror.prototype.isArray = function() {
381 return this instanceof ArrayMirror;
386 * Check whether the mirror reflects a date.
387 * @returns {boolean} True if the mirror reflects a date
389 Mirror.prototype.isDate = function() {
390 return this instanceof DateMirror;
395 * Check whether the mirror reflects a regular expression.
396 * @returns {boolean} True if the mirror reflects a regular expression
398 Mirror.prototype.isRegExp = function() {
399 return this instanceof RegExpMirror;
404 * Check whether the mirror reflects an error.
405 * @returns {boolean} True if the mirror reflects an error
407 Mirror.prototype.isError = function() {
408 return this instanceof ErrorMirror;
413 * Check whether the mirror reflects a promise.
414 * @returns {boolean} True if the mirror reflects a promise
416 Mirror.prototype.isPromise = function() {
417 return this instanceof PromiseMirror;
422 * Check whether the mirror reflects a generator object.
423 * @returns {boolean} True if the mirror reflects a generator object
425 Mirror.prototype.isGenerator = function() {
426 return this instanceof GeneratorMirror;
431 * Check whether the mirror reflects a property.
432 * @returns {boolean} True if the mirror reflects a property
434 Mirror.prototype.isProperty = function() {
435 return this instanceof PropertyMirror;
440 * Check whether the mirror reflects an internal property.
441 * @returns {boolean} True if the mirror reflects an internal property
443 Mirror.prototype.isInternalProperty = function() {
444 return this instanceof InternalPropertyMirror;
449 * Check whether the mirror reflects a stack frame.
450 * @returns {boolean} True if the mirror reflects a stack frame
452 Mirror.prototype.isFrame = function() {
453 return this instanceof FrameMirror;
458 * Check whether the mirror reflects a script.
459 * @returns {boolean} True if the mirror reflects a script
461 Mirror.prototype.isScript = function() {
462 return this instanceof ScriptMirror;
467 * Check whether the mirror reflects a context.
468 * @returns {boolean} True if the mirror reflects a context
470 Mirror.prototype.isContext = function() {
471 return this instanceof ContextMirror;
476 * Check whether the mirror reflects a scope.
477 * @returns {boolean} True if the mirror reflects a scope
479 Mirror.prototype.isScope = function() {
480 return this instanceof ScopeMirror;
485 * Check whether the mirror reflects a map.
486 * @returns {boolean} True if the mirror reflects a map
488 Mirror.prototype.isMap = function() {
489 return this instanceof MapMirror;
494 * Check whether the mirror reflects a set.
495 * @returns {boolean} True if the mirror reflects a set
497 Mirror.prototype.isSet = function() {
498 return this instanceof SetMirror;
503 * Check whether the mirror reflects an iterator.
504 * @returns {boolean} True if the mirror reflects an iterator
506 Mirror.prototype.isIterator = function() {
507 return this instanceof IteratorMirror;
512 * Allocate a handle id for this object.
514 Mirror.prototype.allocateHandle_ = function() {
515 if (mirror_cache_enabled_) this.handle_ = next_handle_++;
520 * Allocate a transient handle id for this object. Transient handles are
523 Mirror.prototype.allocateTransientHandle_ = function() {
524 this.handle_ = next_transient_handle_--;
528 Mirror.prototype.toText = function() {
529 // Simpel to text which is used when on specialization in subclass.
530 return "#<" + this.constructor.name + ">";
535 * Base class for all value mirror objects.
536 * @param {string} type The type of the mirror
537 * @param {value} value The value reflected by this mirror
538 * @param {boolean} transient indicate whether this object is transient with a
543 function ValueMirror(type, value, transient) {
544 %_CallFunction(this, type, Mirror);
547 this.allocateHandle_();
549 this.allocateTransientHandle_();
552 inherits(ValueMirror, Mirror);
555 Mirror.prototype.handle = function() {
561 * Check whether this is a primitive value.
562 * @return {boolean} True if the mirror reflects a primitive value
564 ValueMirror.prototype.isPrimitive = function() {
565 var type = this.type();
566 return type === 'undefined' ||
568 type === 'boolean' ||
576 * Get the actual value reflected by this mirror.
577 * @return {value} The value reflected by this mirror
579 ValueMirror.prototype.value = function() {
585 * Mirror object for Undefined.
587 * @extends ValueMirror
589 function UndefinedMirror() {
590 %_CallFunction(this, MirrorType.UNDEFINED_TYPE, UNDEFINED, ValueMirror);
592 inherits(UndefinedMirror, ValueMirror);
595 UndefinedMirror.prototype.toText = function() {
601 * Mirror object for null.
603 * @extends ValueMirror
605 function NullMirror() {
606 %_CallFunction(this, MirrorType.NULL_TYPE, null, ValueMirror);
608 inherits(NullMirror, ValueMirror);
611 NullMirror.prototype.toText = function() {
617 * Mirror object for boolean values.
618 * @param {boolean} value The boolean value reflected by this mirror
620 * @extends ValueMirror
622 function BooleanMirror(value) {
623 %_CallFunction(this, MirrorType.BOOLEAN_TYPE, value, ValueMirror);
625 inherits(BooleanMirror, ValueMirror);
628 BooleanMirror.prototype.toText = function() {
629 return this.value_ ? 'true' : 'false';
634 * Mirror object for number values.
635 * @param {number} value The number value reflected by this mirror
637 * @extends ValueMirror
639 function NumberMirror(value) {
640 %_CallFunction(this, MirrorType.NUMBER_TYPE, value, ValueMirror);
642 inherits(NumberMirror, ValueMirror);
645 NumberMirror.prototype.toText = function() {
646 return %_NumberToString(this.value_);
651 * Mirror object for string values.
652 * @param {string} value The string value reflected by this mirror
654 * @extends ValueMirror
656 function StringMirror(value) {
657 %_CallFunction(this, MirrorType.STRING_TYPE, value, ValueMirror);
659 inherits(StringMirror, ValueMirror);
662 StringMirror.prototype.length = function() {
663 return this.value_.length;
666 StringMirror.prototype.getTruncatedValue = function(maxLength) {
667 if (maxLength != -1 && this.length() > maxLength) {
668 return this.value_.substring(0, maxLength) +
669 '... (length: ' + this.length() + ')';
674 StringMirror.prototype.toText = function() {
675 return this.getTruncatedValue(kMaxProtocolStringLength);
680 * Mirror object for a Symbol
681 * @param {Object} value The Symbol
685 function SymbolMirror(value) {
686 %_CallFunction(this, MirrorType.SYMBOL_TYPE, value, ValueMirror);
688 inherits(SymbolMirror, ValueMirror);
691 SymbolMirror.prototype.description = function() {
692 return %SymbolDescription(%_ValueOf(this.value_));
696 SymbolMirror.prototype.toText = function() {
697 return %_CallFunction(this.value_, builtins.$symbolToString);
702 * Mirror object for objects.
703 * @param {object} value The object reflected by this mirror
704 * @param {boolean} transient indicate whether this object is transient with a
707 * @extends ValueMirror
709 function ObjectMirror(value, type, transient) {
710 type = type || MirrorType.OBJECT_TYPE;
711 %_CallFunction(this, type, value, transient, ValueMirror);
713 inherits(ObjectMirror, ValueMirror);
716 ObjectMirror.prototype.className = function() {
717 return %_ClassOf(this.value_);
721 ObjectMirror.prototype.constructorFunction = function() {
722 return MakeMirror(%DebugGetProperty(this.value_, 'constructor'));
726 ObjectMirror.prototype.prototypeObject = function() {
727 return MakeMirror(%DebugGetProperty(this.value_, 'prototype'));
731 ObjectMirror.prototype.protoObject = function() {
732 return MakeMirror(%DebugGetPrototype(this.value_));
736 ObjectMirror.prototype.hasNamedInterceptor = function() {
737 // Get information on interceptors for this object.
738 var x = %GetInterceptorInfo(this.value_);
743 ObjectMirror.prototype.hasIndexedInterceptor = function() {
744 // Get information on interceptors for this object.
745 var x = %GetInterceptorInfo(this.value_);
750 // Get all own property names except for private symbols.
751 function TryGetPropertyNames(object) {
753 // TODO(yangguo): Should there be a special debugger implementation of
754 // %GetOwnPropertyNames that doesn't perform access checks?
755 return %GetOwnPropertyNames(object, PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL);
757 // Might have hit a failed access check.
764 * Return the property names for this object.
765 * @param {number} kind Indicate whether named, indexed or both kinds of
766 * properties are requested
767 * @param {number} limit Limit the number of names returend to the specified
769 * @return {Array} Property names for this object
771 ObjectMirror.prototype.propertyNames = function(kind, limit) {
772 // Find kind and limit and allocate array for the result
773 kind = kind || PropertyKind.Named | PropertyKind.Indexed;
779 // Find all the named properties.
780 if (kind & PropertyKind.Named) {
781 propertyNames = TryGetPropertyNames(this.value_);
782 total += propertyNames.length;
784 // Get names for named interceptor properties if any.
785 if (this.hasNamedInterceptor() && (kind & PropertyKind.Named)) {
786 var namedInterceptorNames =
787 %GetNamedInterceptorPropertyNames(this.value_);
788 if (namedInterceptorNames) {
789 propertyNames = propertyNames.concat(namedInterceptorNames);
790 total += namedInterceptorNames.length;
795 // Find all the indexed properties.
796 if (kind & PropertyKind.Indexed) {
797 // Get own element names.
798 elementNames = %GetOwnElementNames(this.value_);
799 total += elementNames.length;
801 // Get names for indexed interceptor properties.
802 if (this.hasIndexedInterceptor() && (kind & PropertyKind.Indexed)) {
803 var indexedInterceptorNames =
804 %GetIndexedInterceptorElementNames(this.value_);
805 if (indexedInterceptorNames) {
806 elementNames = elementNames.concat(indexedInterceptorNames);
807 total += indexedInterceptorNames.length;
811 limit = MathMin(limit || total, total);
813 var names = new GlobalArray(limit);
816 // Copy names for named properties.
817 if (kind & PropertyKind.Named) {
818 for (var i = 0; index < limit && i < propertyNames.length; i++) {
819 names[index++] = propertyNames[i];
823 // Copy names for indexed properties.
824 if (kind & PropertyKind.Indexed) {
825 for (var i = 0; index < limit && i < elementNames.length; i++) {
826 names[index++] = elementNames[i];
835 * Return the properties for this object as an array of PropertyMirror objects.
836 * @param {number} kind Indicate whether named, indexed or both kinds of
837 * properties are requested
838 * @param {number} limit Limit the number of properties returned to the
840 * @return {Array} Property mirrors for this object
842 ObjectMirror.prototype.properties = function(kind, limit) {
843 var names = this.propertyNames(kind, limit);
844 var properties = new GlobalArray(names.length);
845 for (var i = 0; i < names.length; i++) {
846 properties[i] = this.property(names[i]);
854 * Return the internal properties for this object as an array of
855 * InternalPropertyMirror objects.
856 * @return {Array} Property mirrors for this object
858 ObjectMirror.prototype.internalProperties = function() {
859 return ObjectMirror.GetInternalProperties(this.value_);
863 ObjectMirror.prototype.property = function(name) {
864 var details = %DebugGetPropertyDetails(this.value_, TO_NAME(name));
866 return new PropertyMirror(this, name, details);
870 return GetUndefinedMirror();
876 * Try to find a property from its value.
877 * @param {Mirror} value The property value to look for
878 * @return {PropertyMirror} The property with the specified value. If no
879 * property was found with the specified value UndefinedMirror is returned
881 ObjectMirror.prototype.lookupProperty = function(value) {
882 var properties = this.properties();
884 // Look for property value in properties.
885 for (var i = 0; i < properties.length; i++) {
887 // Skip properties which are defined through assessors.
888 var property = properties[i];
889 if (property.propertyType() != PropertyType.AccessorConstant) {
890 if (%_ObjectEquals(property.value_, value.value_)) {
897 return GetUndefinedMirror();
902 * Returns objects which has direct references to this object
903 * @param {number} opt_max_objects Optional parameter specifying the maximum
904 * number of referencing objects to return.
905 * @return {Array} The objects which has direct references to this object.
907 ObjectMirror.prototype.referencedBy = function(opt_max_objects) {
908 // Find all objects with direct references to this object.
909 var result = %DebugReferencedBy(this.value_,
910 Mirror.prototype, opt_max_objects || 0);
912 // Make mirrors for all the references found.
913 for (var i = 0; i < result.length; i++) {
914 result[i] = MakeMirror(result[i]);
921 ObjectMirror.prototype.toText = function() {
923 var ctor = this.constructorFunction();
924 if (!ctor.isFunction()) {
925 name = this.className();
929 name = this.className();
932 return '#<' + name + '>';
937 * Return the internal properties of the value, such as [[PrimitiveValue]] of
938 * scalar wrapper objects, properties of the bound function and properties of
940 * This method is done static to be accessible from Debug API with the bare
941 * values without mirrors.
942 * @return {Array} array (possibly empty) of InternalProperty instances
944 ObjectMirror.GetInternalProperties = function(value) {
945 var properties = %DebugGetInternalProperties(value);
947 for (var i = 0; i < properties.length; i += 2) {
948 result.push(new InternalPropertyMirror(properties[i], properties[i + 1]));
955 * Mirror object for functions.
956 * @param {function} value The function object reflected by this mirror.
958 * @extends ObjectMirror
960 function FunctionMirror(value) {
961 %_CallFunction(this, value, MirrorType.FUNCTION_TYPE, ObjectMirror);
962 this.resolved_ = true;
964 inherits(FunctionMirror, ObjectMirror);
968 * Returns whether the function is resolved.
969 * @return {boolean} True if the function is resolved. Unresolved functions can
970 * only originate as functions from stack frames
972 FunctionMirror.prototype.resolved = function() {
973 return this.resolved_;
978 * Returns the name of the function.
979 * @return {string} Name of the function
981 FunctionMirror.prototype.name = function() {
982 return %FunctionGetName(this.value_);
987 * Returns the inferred name of the function.
988 * @return {string} Name of the function
990 FunctionMirror.prototype.inferredName = function() {
991 return %FunctionGetInferredName(this.value_);
996 * Returns the source code for the function.
997 * @return {string or undefined} The source code for the function. If the
998 * function is not resolved undefined will be returned.
1000 FunctionMirror.prototype.source = function() {
1001 // Return source if function is resolved. Otherwise just fall through to
1002 // return undefined.
1003 if (this.resolved()) {
1004 return FunctionSourceString(this.value_);
1010 * Returns the script object for the function.
1011 * @return {ScriptMirror or undefined} Script object for the function or
1012 * undefined if the function has no script
1014 FunctionMirror.prototype.script = function() {
1015 // Return script if function is resolved. Otherwise just fall through
1016 // to return undefined.
1017 if (this.resolved()) {
1019 return this.script_;
1021 var script = %FunctionGetScript(this.value_);
1023 return this.script_ = MakeMirror(script);
1030 * Returns the script source position for the function. Only makes sense
1031 * for functions which has a script defined.
1032 * @return {Number or undefined} in-script position for the function
1034 FunctionMirror.prototype.sourcePosition_ = function() {
1035 // Return position if function is resolved. Otherwise just fall
1036 // through to return undefined.
1037 if (this.resolved()) {
1038 return %FunctionGetScriptSourcePosition(this.value_);
1044 * Returns the script source location object for the function. Only makes sense
1045 * for functions which has a script defined.
1046 * @return {Location or undefined} in-script location for the function begin
1048 FunctionMirror.prototype.sourceLocation = function() {
1049 if (this.resolved()) {
1050 var script = this.script();
1052 return script.locationFromPosition(this.sourcePosition_(), true);
1059 * Returns objects constructed by this function.
1060 * @param {number} opt_max_instances Optional parameter specifying the maximum
1061 * number of instances to return.
1062 * @return {Array or undefined} The objects constructed by this function.
1064 FunctionMirror.prototype.constructedBy = function(opt_max_instances) {
1065 if (this.resolved()) {
1066 // Find all objects constructed from this function.
1067 var result = %DebugConstructedBy(this.value_, opt_max_instances || 0);
1069 // Make mirrors for all the instances found.
1070 for (var i = 0; i < result.length; i++) {
1071 result[i] = MakeMirror(result[i]);
1081 FunctionMirror.prototype.scopeCount = function() {
1082 if (this.resolved()) {
1083 if (IS_UNDEFINED(this.scopeCount_)) {
1084 this.scopeCount_ = %GetFunctionScopeCount(this.value());
1086 return this.scopeCount_;
1093 FunctionMirror.prototype.scope = function(index) {
1094 if (this.resolved()) {
1095 return new ScopeMirror(UNDEFINED, this, index);
1100 FunctionMirror.prototype.toText = function() {
1101 return this.source();
1106 * Mirror object for unresolved functions.
1107 * @param {string} value The name for the unresolved function reflected by this
1110 * @extends ObjectMirror
1112 function UnresolvedFunctionMirror(value) {
1113 // Construct this using the ValueMirror as an unresolved function is not a
1114 // real object but just a string.
1115 %_CallFunction(this, MirrorType.FUNCTION_TYPE, value, ValueMirror);
1116 this.propertyCount_ = 0;
1117 this.elementCount_ = 0;
1118 this.resolved_ = false;
1120 inherits(UnresolvedFunctionMirror, FunctionMirror);
1123 UnresolvedFunctionMirror.prototype.className = function() {
1128 UnresolvedFunctionMirror.prototype.constructorFunction = function() {
1129 return GetUndefinedMirror();
1133 UnresolvedFunctionMirror.prototype.prototypeObject = function() {
1134 return GetUndefinedMirror();
1138 UnresolvedFunctionMirror.prototype.protoObject = function() {
1139 return GetUndefinedMirror();
1143 UnresolvedFunctionMirror.prototype.name = function() {
1148 UnresolvedFunctionMirror.prototype.inferredName = function() {
1153 UnresolvedFunctionMirror.prototype.propertyNames = function(kind, limit) {
1159 * Mirror object for arrays.
1160 * @param {Array} value The Array object reflected by this mirror
1162 * @extends ObjectMirror
1164 function ArrayMirror(value) {
1165 %_CallFunction(this, value, ObjectMirror);
1167 inherits(ArrayMirror, ObjectMirror);
1170 ArrayMirror.prototype.length = function() {
1171 return this.value_.length;
1175 ArrayMirror.prototype.indexedPropertiesFromRange = function(opt_from_index,
1177 var from_index = opt_from_index || 0;
1178 var to_index = opt_to_index || this.length() - 1;
1179 if (from_index > to_index) return new GlobalArray();
1180 var values = new GlobalArray(to_index - from_index + 1);
1181 for (var i = from_index; i <= to_index; i++) {
1182 var details = %DebugGetPropertyDetails(this.value_, ToString(i));
1185 value = new PropertyMirror(this, i, details);
1187 value = GetUndefinedMirror();
1189 values[i - from_index] = value;
1196 * Mirror object for dates.
1197 * @param {Date} value The Date object reflected by this mirror
1199 * @extends ObjectMirror
1201 function DateMirror(value) {
1202 %_CallFunction(this, value, ObjectMirror);
1204 inherits(DateMirror, ObjectMirror);
1207 DateMirror.prototype.toText = function() {
1208 var s = JSONStringify(this.value_);
1209 return s.substring(1, s.length - 1); // cut quotes
1214 * Mirror object for regular expressions.
1215 * @param {RegExp} value The RegExp object reflected by this mirror
1217 * @extends ObjectMirror
1219 function RegExpMirror(value) {
1220 %_CallFunction(this, value, MirrorType.REGEXP_TYPE, ObjectMirror);
1222 inherits(RegExpMirror, ObjectMirror);
1226 * Returns the source to the regular expression.
1227 * @return {string or undefined} The source to the regular expression
1229 RegExpMirror.prototype.source = function() {
1230 return this.value_.source;
1235 * Returns whether this regular expression has the global (g) flag set.
1236 * @return {boolean} Value of the global flag
1238 RegExpMirror.prototype.global = function() {
1239 return this.value_.global;
1244 * Returns whether this regular expression has the ignore case (i) flag set.
1245 * @return {boolean} Value of the ignore case flag
1247 RegExpMirror.prototype.ignoreCase = function() {
1248 return this.value_.ignoreCase;
1253 * Returns whether this regular expression has the multiline (m) flag set.
1254 * @return {boolean} Value of the multiline flag
1256 RegExpMirror.prototype.multiline = function() {
1257 return this.value_.multiline;
1262 * Returns whether this regular expression has the sticky (y) flag set.
1263 * @return {boolean} Value of the sticky flag
1265 RegExpMirror.prototype.sticky = function() {
1266 return this.value_.sticky;
1271 * Returns whether this regular expression has the unicode (u) flag set.
1272 * @return {boolean} Value of the unicode flag
1274 RegExpMirror.prototype.unicode = function() {
1275 return this.value_.unicode;
1279 RegExpMirror.prototype.toText = function() {
1280 // Simpel to text which is used when on specialization in subclass.
1281 return "/" + this.source() + "/";
1286 * Mirror object for error objects.
1287 * @param {Error} value The error object reflected by this mirror
1289 * @extends ObjectMirror
1291 function ErrorMirror(value) {
1292 %_CallFunction(this, value, MirrorType.ERROR_TYPE, ObjectMirror);
1294 inherits(ErrorMirror, ObjectMirror);
1298 * Returns the message for this eror object.
1299 * @return {string or undefined} The message for this eror object
1301 ErrorMirror.prototype.message = function() {
1302 return this.value_.message;
1306 ErrorMirror.prototype.toText = function() {
1307 // Use the same text representation as in messages.js.
1310 text = %_CallFunction(this.value_, builtins.$errorToString);
1319 * Mirror object for a Promise object.
1320 * @param {Object} value The Promise object
1322 * @extends ObjectMirror
1324 function PromiseMirror(value) {
1325 %_CallFunction(this, value, MirrorType.PROMISE_TYPE, ObjectMirror);
1327 inherits(PromiseMirror, ObjectMirror);
1330 function PromiseGetStatus_(value) {
1331 var status = %DebugGetProperty(value, promiseStatusSymbol);
1332 if (status == 0) return "pending";
1333 if (status == 1) return "resolved";
1338 function PromiseGetValue_(value) {
1339 return %DebugGetProperty(value, promiseValueSymbol);
1343 PromiseMirror.prototype.status = function() {
1344 return PromiseGetStatus_(this.value_);
1348 PromiseMirror.prototype.promiseValue = function() {
1349 return MakeMirror(PromiseGetValue_(this.value_));
1353 function MapMirror(value) {
1354 %_CallFunction(this, value, MirrorType.MAP_TYPE, ObjectMirror);
1356 inherits(MapMirror, ObjectMirror);
1360 * Returns an array of key/value pairs of a map.
1361 * This will keep keys alive for WeakMaps.
1363 * @param {number=} opt_limit Max elements to return.
1364 * @returns {Array.<Object>} Array of key/value pairs of a map.
1366 MapMirror.prototype.entries = function(opt_limit) {
1369 if (IS_WEAKMAP(this.value_)) {
1370 var entries = %GetWeakMapEntries(this.value_, opt_limit || 0);
1371 for (var i = 0; i < entries.length; i += 2) {
1374 value: entries[i + 1]
1380 var iter = %_CallFunction(this.value_, builtins.$mapEntries);
1382 while ((!opt_limit || result.length < opt_limit) &&
1383 !(next = iter.next()).done) {
1386 value: next.value[1]
1393 function SetMirror(value) {
1394 %_CallFunction(this, value, MirrorType.SET_TYPE, ObjectMirror);
1396 inherits(SetMirror, ObjectMirror);
1399 function IteratorGetValues_(iter, next_function, opt_limit) {
1402 while ((!opt_limit || result.length < opt_limit) &&
1403 !(next = %_CallFunction(iter, next_function)).done) {
1404 result.push(next.value);
1411 * Returns an array of elements of a set.
1412 * This will keep elements alive for WeakSets.
1414 * @param {number=} opt_limit Max elements to return.
1415 * @returns {Array.<Object>} Array of elements of a set.
1417 SetMirror.prototype.values = function(opt_limit) {
1418 if (IS_WEAKSET(this.value_)) {
1419 return %GetWeakSetValues(this.value_, opt_limit || 0);
1422 var iter = %_CallFunction(this.value_, builtins.$setValues);
1423 return IteratorGetValues_(iter, builtins.$setIteratorNext, opt_limit);
1427 function IteratorMirror(value) {
1428 %_CallFunction(this, value, MirrorType.ITERATOR_TYPE, ObjectMirror);
1430 inherits(IteratorMirror, ObjectMirror);
1434 * Returns a preview of elements of an iterator.
1435 * Does not change the backing iterator state.
1437 * @param {number=} opt_limit Max elements to return.
1438 * @returns {Array.<Object>} Array of elements of an iterator.
1440 IteratorMirror.prototype.preview = function(opt_limit) {
1441 if (IS_MAP_ITERATOR(this.value_)) {
1442 return IteratorGetValues_(%MapIteratorClone(this.value_),
1443 builtins.$mapIteratorNext,
1445 } else if (IS_SET_ITERATOR(this.value_)) {
1446 return IteratorGetValues_(%SetIteratorClone(this.value_),
1447 builtins.$setIteratorNext,
1454 * Mirror object for a Generator object.
1455 * @param {Object} data The Generator object
1459 function GeneratorMirror(value) {
1460 %_CallFunction(this, value, MirrorType.GENERATOR_TYPE, ObjectMirror);
1462 inherits(GeneratorMirror, ObjectMirror);
1465 function GeneratorGetStatus_(value) {
1466 var continuation = %GeneratorGetContinuation(value);
1467 if (continuation < 0) return "running";
1468 if (continuation == 0) return "closed";
1473 GeneratorMirror.prototype.status = function() {
1474 return GeneratorGetStatus_(this.value_);
1478 GeneratorMirror.prototype.sourcePosition_ = function() {
1479 return %GeneratorGetSourcePosition(this.value_);
1483 GeneratorMirror.prototype.sourceLocation = function() {
1484 var pos = this.sourcePosition_();
1485 if (!IS_UNDEFINED(pos)) {
1486 var script = this.func().script();
1488 return script.locationFromPosition(pos, true);
1494 GeneratorMirror.prototype.func = function() {
1496 this.func_ = MakeMirror(%GeneratorGetFunction(this.value_));
1502 GeneratorMirror.prototype.context = function() {
1503 if (!this.context_) {
1504 this.context_ = new ContextMirror(%GeneratorGetContext(this.value_));
1506 return this.context_;
1510 GeneratorMirror.prototype.receiver = function() {
1511 if (!this.receiver_) {
1512 this.receiver_ = MakeMirror(%GeneratorGetReceiver(this.value_));
1514 return this.receiver_;
1519 * Base mirror object for properties.
1520 * @param {ObjectMirror} mirror The mirror object having this property
1521 * @param {string} name The name of the property
1522 * @param {Array} details Details about the property
1526 function PropertyMirror(mirror, name, details) {
1527 %_CallFunction(this, MirrorType.PROPERTY_TYPE, Mirror);
1528 this.mirror_ = mirror;
1530 this.value_ = details[0];
1531 this.details_ = details[1];
1532 this.is_interceptor_ = details[2];
1533 if (details.length > 3) {
1534 this.exception_ = details[3];
1535 this.getter_ = details[4];
1536 this.setter_ = details[5];
1539 inherits(PropertyMirror, Mirror);
1542 PropertyMirror.prototype.isReadOnly = function() {
1543 return (this.attributes() & PropertyAttribute.ReadOnly) != 0;
1547 PropertyMirror.prototype.isEnum = function() {
1548 return (this.attributes() & PropertyAttribute.DontEnum) == 0;
1552 PropertyMirror.prototype.canDelete = function() {
1553 return (this.attributes() & PropertyAttribute.DontDelete) == 0;
1557 PropertyMirror.prototype.name = function() {
1562 PropertyMirror.prototype.isIndexed = function() {
1563 for (var i = 0; i < this.name_.length; i++) {
1564 if (this.name_[i] < '0' || '9' < this.name_[i]) {
1572 PropertyMirror.prototype.value = function() {
1573 return MakeMirror(this.value_, false);
1578 * Returns whether this property value is an exception.
1579 * @return {booolean} True if this property value is an exception
1581 PropertyMirror.prototype.isException = function() {
1582 return this.exception_ ? true : false;
1586 PropertyMirror.prototype.attributes = function() {
1587 return %DebugPropertyAttributesFromDetails(this.details_);
1591 PropertyMirror.prototype.propertyType = function() {
1592 return %DebugPropertyTypeFromDetails(this.details_);
1596 PropertyMirror.prototype.insertionIndex = function() {
1597 return %DebugPropertyIndexFromDetails(this.details_);
1602 * Returns whether this property has a getter defined through __defineGetter__.
1603 * @return {booolean} True if this property has a getter
1605 PropertyMirror.prototype.hasGetter = function() {
1606 return this.getter_ ? true : false;
1611 * Returns whether this property has a setter defined through __defineSetter__.
1612 * @return {booolean} True if this property has a setter
1614 PropertyMirror.prototype.hasSetter = function() {
1615 return this.setter_ ? true : false;
1620 * Returns the getter for this property defined through __defineGetter__.
1621 * @return {Mirror} FunctionMirror reflecting the getter function or
1622 * UndefinedMirror if there is no getter for this property
1624 PropertyMirror.prototype.getter = function() {
1625 if (this.hasGetter()) {
1626 return MakeMirror(this.getter_);
1628 return GetUndefinedMirror();
1634 * Returns the setter for this property defined through __defineSetter__.
1635 * @return {Mirror} FunctionMirror reflecting the setter function or
1636 * UndefinedMirror if there is no setter for this property
1638 PropertyMirror.prototype.setter = function() {
1639 if (this.hasSetter()) {
1640 return MakeMirror(this.setter_);
1642 return GetUndefinedMirror();
1648 * Returns whether this property is natively implemented by the host or a set
1649 * through JavaScript code.
1650 * @return {boolean} True if the property is
1651 * UndefinedMirror if there is no setter for this property
1653 PropertyMirror.prototype.isNative = function() {
1654 return this.is_interceptor_ ||
1655 ((this.propertyType() == PropertyType.AccessorConstant) &&
1656 !this.hasGetter() && !this.hasSetter());
1661 * Mirror object for internal properties. Internal property reflects properties
1662 * not accessible from user code such as [[BoundThis]] in bound function.
1663 * Their names are merely symbolic.
1664 * @param {string} name The name of the property
1665 * @param {value} property value
1669 function InternalPropertyMirror(name, value) {
1670 %_CallFunction(this, MirrorType.INTERNAL_PROPERTY_TYPE, Mirror);
1672 this.value_ = value;
1674 inherits(InternalPropertyMirror, Mirror);
1677 InternalPropertyMirror.prototype.name = function() {
1682 InternalPropertyMirror.prototype.value = function() {
1683 return MakeMirror(this.value_, false);
1687 var kFrameDetailsFrameIdIndex = 0;
1688 var kFrameDetailsReceiverIndex = 1;
1689 var kFrameDetailsFunctionIndex = 2;
1690 var kFrameDetailsArgumentCountIndex = 3;
1691 var kFrameDetailsLocalCountIndex = 4;
1692 var kFrameDetailsSourcePositionIndex = 5;
1693 var kFrameDetailsConstructCallIndex = 6;
1694 var kFrameDetailsAtReturnIndex = 7;
1695 var kFrameDetailsFlagsIndex = 8;
1696 var kFrameDetailsFirstDynamicIndex = 9;
1698 var kFrameDetailsNameIndex = 0;
1699 var kFrameDetailsValueIndex = 1;
1700 var kFrameDetailsNameValueSize = 2;
1702 var kFrameDetailsFlagDebuggerFrameMask = 1 << 0;
1703 var kFrameDetailsFlagOptimizedFrameMask = 1 << 1;
1704 var kFrameDetailsFlagInlinedFrameIndexMask = 7 << 2;
1707 * Wrapper for the frame details information retreived from the VM. The frame
1708 * details from the VM is an array with the following content. See runtime.cc
1709 * Runtime_GetFrameDetails.
1715 * 5: Source position
1718 * 8: Flags (debugger frame, optimized frame, inlined frame index)
1719 * Arguments name, value
1720 * Locals name, value
1721 * Return value if any
1722 * @param {number} break_id Current break id
1723 * @param {number} index Frame number
1726 function FrameDetails(break_id, index) {
1727 this.break_id_ = break_id;
1728 this.details_ = %GetFrameDetails(break_id, index);
1732 FrameDetails.prototype.frameId = function() {
1733 %CheckExecutionState(this.break_id_);
1734 return this.details_[kFrameDetailsFrameIdIndex];
1738 FrameDetails.prototype.receiver = function() {
1739 %CheckExecutionState(this.break_id_);
1740 return this.details_[kFrameDetailsReceiverIndex];
1744 FrameDetails.prototype.func = function() {
1745 %CheckExecutionState(this.break_id_);
1746 return this.details_[kFrameDetailsFunctionIndex];
1750 FrameDetails.prototype.isConstructCall = function() {
1751 %CheckExecutionState(this.break_id_);
1752 return this.details_[kFrameDetailsConstructCallIndex];
1756 FrameDetails.prototype.isAtReturn = function() {
1757 %CheckExecutionState(this.break_id_);
1758 return this.details_[kFrameDetailsAtReturnIndex];
1762 FrameDetails.prototype.isDebuggerFrame = function() {
1763 %CheckExecutionState(this.break_id_);
1764 var f = kFrameDetailsFlagDebuggerFrameMask;
1765 return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
1769 FrameDetails.prototype.isOptimizedFrame = function() {
1770 %CheckExecutionState(this.break_id_);
1771 var f = kFrameDetailsFlagOptimizedFrameMask;
1772 return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
1776 FrameDetails.prototype.isInlinedFrame = function() {
1777 return this.inlinedFrameIndex() > 0;
1781 FrameDetails.prototype.inlinedFrameIndex = function() {
1782 %CheckExecutionState(this.break_id_);
1783 var f = kFrameDetailsFlagInlinedFrameIndexMask;
1784 return (this.details_[kFrameDetailsFlagsIndex] & f) >> 2;
1788 FrameDetails.prototype.argumentCount = function() {
1789 %CheckExecutionState(this.break_id_);
1790 return this.details_[kFrameDetailsArgumentCountIndex];
1794 FrameDetails.prototype.argumentName = function(index) {
1795 %CheckExecutionState(this.break_id_);
1796 if (index >= 0 && index < this.argumentCount()) {
1797 return this.details_[kFrameDetailsFirstDynamicIndex +
1798 index * kFrameDetailsNameValueSize +
1799 kFrameDetailsNameIndex];
1804 FrameDetails.prototype.argumentValue = function(index) {
1805 %CheckExecutionState(this.break_id_);
1806 if (index >= 0 && index < this.argumentCount()) {
1807 return this.details_[kFrameDetailsFirstDynamicIndex +
1808 index * kFrameDetailsNameValueSize +
1809 kFrameDetailsValueIndex];
1814 FrameDetails.prototype.localCount = function() {
1815 %CheckExecutionState(this.break_id_);
1816 return this.details_[kFrameDetailsLocalCountIndex];
1820 FrameDetails.prototype.sourcePosition = function() {
1821 %CheckExecutionState(this.break_id_);
1822 return this.details_[kFrameDetailsSourcePositionIndex];
1826 FrameDetails.prototype.localName = function(index) {
1827 %CheckExecutionState(this.break_id_);
1828 if (index >= 0 && index < this.localCount()) {
1829 var locals_offset = kFrameDetailsFirstDynamicIndex +
1830 this.argumentCount() * kFrameDetailsNameValueSize;
1831 return this.details_[locals_offset +
1832 index * kFrameDetailsNameValueSize +
1833 kFrameDetailsNameIndex];
1838 FrameDetails.prototype.localValue = function(index) {
1839 %CheckExecutionState(this.break_id_);
1840 if (index >= 0 && index < this.localCount()) {
1841 var locals_offset = kFrameDetailsFirstDynamicIndex +
1842 this.argumentCount() * kFrameDetailsNameValueSize;
1843 return this.details_[locals_offset +
1844 index * kFrameDetailsNameValueSize +
1845 kFrameDetailsValueIndex];
1850 FrameDetails.prototype.returnValue = function() {
1851 %CheckExecutionState(this.break_id_);
1852 var return_value_offset =
1853 kFrameDetailsFirstDynamicIndex +
1854 (this.argumentCount() + this.localCount()) * kFrameDetailsNameValueSize;
1855 if (this.details_[kFrameDetailsAtReturnIndex]) {
1856 return this.details_[return_value_offset];
1861 FrameDetails.prototype.scopeCount = function() {
1862 if (IS_UNDEFINED(this.scopeCount_)) {
1863 this.scopeCount_ = %GetScopeCount(this.break_id_, this.frameId());
1865 return this.scopeCount_;
1869 FrameDetails.prototype.stepInPositionsImpl = function() {
1870 return %GetStepInPositions(this.break_id_, this.frameId());
1875 * Mirror object for stack frames.
1876 * @param {number} break_id The break id in the VM for which this frame is
1878 * @param {number} index The frame index (top frame is index 0)
1882 function FrameMirror(break_id, index) {
1883 %_CallFunction(this, MirrorType.FRAME_TYPE, Mirror);
1884 this.break_id_ = break_id;
1885 this.index_ = index;
1886 this.details_ = new FrameDetails(break_id, index);
1888 inherits(FrameMirror, Mirror);
1891 FrameMirror.prototype.details = function() {
1892 return this.details_;
1896 FrameMirror.prototype.index = function() {
1901 FrameMirror.prototype.func = function() {
1906 // Get the function for this frame from the VM.
1907 var f = this.details_.func();
1909 // Create a function mirror. NOTE: MakeMirror cannot be used here as the
1910 // value returned from the VM might be a string if the function for the
1911 // frame is unresolved.
1912 if (IS_FUNCTION(f)) {
1913 return this.func_ = MakeMirror(f);
1915 return new UnresolvedFunctionMirror(f);
1920 FrameMirror.prototype.receiver = function() {
1921 return MakeMirror(this.details_.receiver());
1925 FrameMirror.prototype.isConstructCall = function() {
1926 return this.details_.isConstructCall();
1930 FrameMirror.prototype.isAtReturn = function() {
1931 return this.details_.isAtReturn();
1935 FrameMirror.prototype.isDebuggerFrame = function() {
1936 return this.details_.isDebuggerFrame();
1940 FrameMirror.prototype.isOptimizedFrame = function() {
1941 return this.details_.isOptimizedFrame();
1945 FrameMirror.prototype.isInlinedFrame = function() {
1946 return this.details_.isInlinedFrame();
1950 FrameMirror.prototype.inlinedFrameIndex = function() {
1951 return this.details_.inlinedFrameIndex();
1955 FrameMirror.prototype.argumentCount = function() {
1956 return this.details_.argumentCount();
1960 FrameMirror.prototype.argumentName = function(index) {
1961 return this.details_.argumentName(index);
1965 FrameMirror.prototype.argumentValue = function(index) {
1966 return MakeMirror(this.details_.argumentValue(index));
1970 FrameMirror.prototype.localCount = function() {
1971 return this.details_.localCount();
1975 FrameMirror.prototype.localName = function(index) {
1976 return this.details_.localName(index);
1980 FrameMirror.prototype.localValue = function(index) {
1981 return MakeMirror(this.details_.localValue(index));
1985 FrameMirror.prototype.returnValue = function() {
1986 return MakeMirror(this.details_.returnValue());
1990 FrameMirror.prototype.sourcePosition = function() {
1991 return this.details_.sourcePosition();
1995 FrameMirror.prototype.sourceLocation = function() {
1996 var func = this.func();
1997 if (func.resolved()) {
1998 var script = func.script();
2000 return script.locationFromPosition(this.sourcePosition(), true);
2006 FrameMirror.prototype.sourceLine = function() {
2007 var location = this.sourceLocation();
2009 return location.line;
2014 FrameMirror.prototype.sourceColumn = function() {
2015 var location = this.sourceLocation();
2017 return location.column;
2022 FrameMirror.prototype.sourceLineText = function() {
2023 var location = this.sourceLocation();
2025 return location.sourceText();
2030 FrameMirror.prototype.scopeCount = function() {
2031 return this.details_.scopeCount();
2035 FrameMirror.prototype.scope = function(index) {
2036 return new ScopeMirror(this, UNDEFINED, index);
2040 FrameMirror.prototype.allScopes = function(opt_ignore_nested_scopes) {
2041 var scopeDetails = %GetAllScopesDetails(this.break_id_,
2042 this.details_.frameId(),
2043 this.details_.inlinedFrameIndex(),
2044 !!opt_ignore_nested_scopes);
2046 for (var i = 0; i < scopeDetails.length; ++i) {
2047 result.push(new ScopeMirror(this, UNDEFINED, i, scopeDetails[i]));
2053 FrameMirror.prototype.stepInPositions = function() {
2054 var script = this.func().script();
2055 var funcOffset = this.func().sourcePosition_();
2057 var stepInRaw = this.details_.stepInPositionsImpl();
2060 for (var i = 0; i < stepInRaw.length; i++) {
2062 var offset = script.locationFromPosition(funcOffset + stepInRaw[i],
2064 serializeLocationFields(offset, posStruct);
2076 FrameMirror.prototype.evaluate = function(source, disable_break,
2077 opt_context_object) {
2078 return MakeMirror(%DebugEvaluate(this.break_id_,
2079 this.details_.frameId(),
2080 this.details_.inlinedFrameIndex(),
2082 ToBoolean(disable_break),
2083 opt_context_object));
2087 FrameMirror.prototype.invocationText = function() {
2088 // Format frame invoaction (receiver, function and arguments).
2090 var func = this.func();
2091 var receiver = this.receiver();
2092 if (this.isConstructCall()) {
2093 // For constructor frames display new followed by the function name.
2095 result += func.name() ? func.name() : '[anonymous]';
2096 } else if (this.isDebuggerFrame()) {
2097 result += '[debugger]';
2099 // If the receiver has a className which is 'global' don't display it.
2100 var display_receiver =
2101 !receiver.className || (receiver.className() != 'global');
2102 if (display_receiver) {
2103 result += receiver.toText();
2105 // Try to find the function as a property in the receiver. Include the
2106 // prototype chain in the lookup.
2107 var property = GetUndefinedMirror();
2108 if (receiver.isObject()) {
2109 for (var r = receiver;
2110 !r.isNull() && property.isUndefined();
2111 r = r.protoObject()) {
2112 property = r.lookupProperty(func);
2115 if (!property.isUndefined()) {
2116 // The function invoked was found on the receiver. Use the property name
2117 // for the backtrace.
2118 if (!property.isIndexed()) {
2119 if (display_receiver) {
2122 result += property.name();
2125 result += property.name();
2128 // Also known as - if the name in the function doesn't match the name
2129 // under which it was looked up.
2130 if (func.name() && func.name() != property.name()) {
2131 result += '(aka ' + func.name() + ')';
2134 // The function invoked was not found on the receiver. Use the function
2135 // name if available for the backtrace.
2136 if (display_receiver) {
2139 result += func.name() ? func.name() : '[anonymous]';
2143 // Render arguments for normal frames.
2144 if (!this.isDebuggerFrame()) {
2146 for (var i = 0; i < this.argumentCount(); i++) {
2147 if (i != 0) result += ', ';
2148 if (this.argumentName(i)) {
2149 result += this.argumentName(i);
2152 result += this.argumentValue(i).toText();
2157 if (this.isAtReturn()) {
2158 result += ' returning ';
2159 result += this.returnValue().toText();
2166 FrameMirror.prototype.sourceAndPositionText = function() {
2167 // Format source and position.
2169 var func = this.func();
2170 if (func.resolved()) {
2171 var script = func.script();
2173 if (script.name()) {
2174 result += script.name();
2176 result += '[unnamed]';
2178 if (!this.isDebuggerFrame()) {
2179 var location = this.sourceLocation();
2181 result += !IS_UNDEFINED(location) ? (location.line + 1) : '?';
2182 result += ' column ';
2183 result += !IS_UNDEFINED(location) ? (location.column + 1) : '?';
2184 if (!IS_UNDEFINED(this.sourcePosition())) {
2185 result += ' (position ' + (this.sourcePosition() + 1) + ')';
2189 result += '[no source]';
2192 result += '[unresolved]';
2199 FrameMirror.prototype.localsText = function() {
2200 // Format local variables.
2202 var locals_count = this.localCount();
2203 if (locals_count > 0) {
2204 for (var i = 0; i < locals_count; ++i) {
2206 result += this.localName(i);
2208 result += this.localValue(i).toText();
2209 if (i < locals_count - 1) result += '\n';
2217 FrameMirror.prototype.restart = function() {
2218 var result = %LiveEditRestartFrame(this.break_id_, this.index_);
2219 if (IS_UNDEFINED(result)) {
2220 result = "Failed to find requested frame";
2226 FrameMirror.prototype.toText = function(opt_locals) {
2228 result += '#' + (this.index() <= 9 ? '0' : '') + this.index();
2230 result += this.invocationText();
2232 result += this.sourceAndPositionText();
2235 result += this.localsText();
2241 var kScopeDetailsTypeIndex = 0;
2242 var kScopeDetailsObjectIndex = 1;
2244 function ScopeDetails(frame, fun, index, opt_details) {
2246 this.break_id_ = frame.break_id_;
2247 this.details_ = opt_details ||
2248 %GetScopeDetails(frame.break_id_,
2249 frame.details_.frameId(),
2250 frame.details_.inlinedFrameIndex(),
2252 this.frame_id_ = frame.details_.frameId();
2253 this.inlined_frame_id_ = frame.details_.inlinedFrameIndex();
2255 this.details_ = opt_details || %GetFunctionScopeDetails(fun.value(), index);
2256 this.fun_value_ = fun.value();
2257 this.break_id_ = UNDEFINED;
2259 this.index_ = index;
2263 ScopeDetails.prototype.type = function() {
2264 if (!IS_UNDEFINED(this.break_id_)) {
2265 %CheckExecutionState(this.break_id_);
2267 return this.details_[kScopeDetailsTypeIndex];
2271 ScopeDetails.prototype.object = function() {
2272 if (!IS_UNDEFINED(this.break_id_)) {
2273 %CheckExecutionState(this.break_id_);
2275 return this.details_[kScopeDetailsObjectIndex];
2279 ScopeDetails.prototype.setVariableValueImpl = function(name, new_value) {
2281 if (!IS_UNDEFINED(this.break_id_)) {
2282 %CheckExecutionState(this.break_id_);
2283 raw_res = %SetScopeVariableValue(this.break_id_, this.frame_id_,
2284 this.inlined_frame_id_, this.index_, name, new_value);
2286 raw_res = %SetScopeVariableValue(this.fun_value_, null, null, this.index_,
2289 if (!raw_res) throw MakeError(kDebugger, "Failed to set variable value");
2294 * Mirror object for scope of frame or function. Either frame or function must
2296 * @param {FrameMirror} frame The frame this scope is a part of
2297 * @param {FunctionMirror} function The function this scope is a part of
2298 * @param {number} index The scope index in the frame
2299 * @param {Array=} opt_details Raw scope details data
2303 function ScopeMirror(frame, fun, index, opt_details) {
2304 %_CallFunction(this, MirrorType.SCOPE_TYPE, Mirror);
2306 this.frame_index_ = frame.index_;
2308 this.frame_index_ = UNDEFINED;
2310 this.scope_index_ = index;
2311 this.details_ = new ScopeDetails(frame, fun, index, opt_details);
2313 inherits(ScopeMirror, Mirror);
2316 ScopeMirror.prototype.details = function() {
2317 return this.details_;
2321 ScopeMirror.prototype.frameIndex = function() {
2322 return this.frame_index_;
2326 ScopeMirror.prototype.scopeIndex = function() {
2327 return this.scope_index_;
2331 ScopeMirror.prototype.scopeType = function() {
2332 return this.details_.type();
2336 ScopeMirror.prototype.scopeObject = function() {
2337 // For local, closure and script scopes create a transient mirror
2338 // as these objects are created on the fly materializing the local
2339 // or closure scopes and therefore will not preserve identity.
2340 var transient = this.scopeType() == ScopeType.Local ||
2341 this.scopeType() == ScopeType.Closure ||
2342 this.scopeType() == ScopeType.Script;
2343 return MakeMirror(this.details_.object(), transient);
2347 ScopeMirror.prototype.setVariableValue = function(name, new_value) {
2348 this.details_.setVariableValueImpl(name, new_value);
2353 * Mirror object for script source.
2354 * @param {Script} script The script object
2358 function ScriptMirror(script) {
2359 %_CallFunction(this, MirrorType.SCRIPT_TYPE, Mirror);
2360 this.script_ = script;
2361 this.context_ = new ContextMirror(script.context_data);
2362 this.allocateHandle_();
2364 inherits(ScriptMirror, Mirror);
2367 ScriptMirror.prototype.value = function() {
2368 return this.script_;
2372 ScriptMirror.prototype.name = function() {
2373 return this.script_.name || this.script_.nameOrSourceURL();
2377 ScriptMirror.prototype.id = function() {
2378 return this.script_.id;
2382 ScriptMirror.prototype.source = function() {
2383 return this.script_.source;
2387 ScriptMirror.prototype.setSource = function(source) {
2388 %DebugSetScriptSource(this.script_, source);
2392 ScriptMirror.prototype.lineOffset = function() {
2393 return this.script_.line_offset;
2397 ScriptMirror.prototype.columnOffset = function() {
2398 return this.script_.column_offset;
2402 ScriptMirror.prototype.data = function() {
2403 return this.script_.data;
2407 ScriptMirror.prototype.scriptType = function() {
2408 return this.script_.type;
2412 ScriptMirror.prototype.compilationType = function() {
2413 return this.script_.compilation_type;
2417 ScriptMirror.prototype.lineCount = function() {
2418 return this.script_.lineCount();
2422 ScriptMirror.prototype.locationFromPosition = function(
2423 position, include_resource_offset) {
2424 return this.script_.locationFromPosition(position, include_resource_offset);
2428 ScriptMirror.prototype.sourceSlice = function (opt_from_line, opt_to_line) {
2429 return this.script_.sourceSlice(opt_from_line, opt_to_line);
2433 ScriptMirror.prototype.context = function() {
2434 return this.context_;
2438 ScriptMirror.prototype.evalFromScript = function() {
2439 return MakeMirror(this.script_.eval_from_script);
2443 ScriptMirror.prototype.evalFromFunctionName = function() {
2444 return MakeMirror(this.script_.eval_from_function_name);
2448 ScriptMirror.prototype.evalFromLocation = function() {
2449 var eval_from_script = this.evalFromScript();
2450 if (!eval_from_script.isUndefined()) {
2451 var position = this.script_.eval_from_script_position;
2452 return eval_from_script.locationFromPosition(position, true);
2457 ScriptMirror.prototype.toText = function() {
2459 result += this.name();
2460 result += ' (lines: ';
2461 if (this.lineOffset() > 0) {
2462 result += this.lineOffset();
2464 result += this.lineOffset() + this.lineCount() - 1;
2466 result += this.lineCount();
2474 * Mirror object for context.
2475 * @param {Object} data The context data
2479 function ContextMirror(data) {
2480 %_CallFunction(this, MirrorType.CONTEXT_TYPE, Mirror);
2482 this.allocateHandle_();
2484 inherits(ContextMirror, Mirror);
2487 ContextMirror.prototype.data = function() {
2493 * Returns a mirror serializer
2495 * @param {boolean} details Set to true to include details
2496 * @param {Object} options Options comtrolling the serialization
2497 * The following options can be set:
2498 * includeSource: include ths full source of scripts
2499 * @returns {MirrorSerializer} mirror serializer
2501 function MakeMirrorSerializer(details, options) {
2502 return new JSONProtocolSerializer(details, options);
2507 * Object for serializing a mirror objects and its direct references.
2508 * @param {boolean} details Indicates whether to include details for the mirror
2512 function JSONProtocolSerializer(details, options) {
2513 this.details_ = details;
2514 this.options_ = options;
2515 this.mirrors_ = [ ];
2520 * Returns a serialization of an object reference. The referenced object are
2521 * added to the serialization state.
2523 * @param {Mirror} mirror The mirror to serialize
2524 * @returns {String} JSON serialization
2526 JSONProtocolSerializer.prototype.serializeReference = function(mirror) {
2527 return this.serialize_(mirror, true, true);
2532 * Returns a serialization of an object value. The referenced objects are
2533 * added to the serialization state.
2535 * @param {Mirror} mirror The mirror to serialize
2536 * @returns {String} JSON serialization
2538 JSONProtocolSerializer.prototype.serializeValue = function(mirror) {
2539 var json = this.serialize_(mirror, false, true);
2545 * Returns a serialization of all the objects referenced.
2547 * @param {Mirror} mirror The mirror to serialize.
2548 * @returns {Array.<Object>} Array of the referenced objects converted to
2551 JSONProtocolSerializer.prototype.serializeReferencedObjects = function() {
2552 // Collect the protocol representation of the referenced objects in an array.
2555 // Get the number of referenced objects.
2556 var count = this.mirrors_.length;
2558 for (var i = 0; i < count; i++) {
2559 content.push(this.serialize_(this.mirrors_[i], false, false));
2566 JSONProtocolSerializer.prototype.includeSource_ = function() {
2567 return this.options_ && this.options_.includeSource;
2571 JSONProtocolSerializer.prototype.inlineRefs_ = function() {
2572 return this.options_ && this.options_.inlineRefs;
2576 JSONProtocolSerializer.prototype.maxStringLength_ = function() {
2577 if (IS_UNDEFINED(this.options_) ||
2578 IS_UNDEFINED(this.options_.maxStringLength)) {
2579 return kMaxProtocolStringLength;
2581 return this.options_.maxStringLength;
2585 JSONProtocolSerializer.prototype.add_ = function(mirror) {
2586 // If this mirror is already in the list just return.
2587 for (var i = 0; i < this.mirrors_.length; i++) {
2588 if (this.mirrors_[i] === mirror) {
2593 // Add the mirror to the list of mirrors to be serialized.
2594 this.mirrors_.push(mirror);
2599 * Formats mirror object to protocol reference object with some data that can
2600 * be used to display the value in debugger.
2601 * @param {Mirror} mirror Mirror to serialize.
2602 * @return {Object} Protocol reference object.
2604 JSONProtocolSerializer.prototype.serializeReferenceWithDisplayData_ =
2607 o.ref = mirror.handle();
2608 o.type = mirror.type();
2609 switch (mirror.type()) {
2610 case MirrorType.UNDEFINED_TYPE:
2611 case MirrorType.NULL_TYPE:
2612 case MirrorType.BOOLEAN_TYPE:
2613 case MirrorType.NUMBER_TYPE:
2614 o.value = mirror.value();
2616 case MirrorType.STRING_TYPE:
2617 o.value = mirror.getTruncatedValue(this.maxStringLength_());
2619 case MirrorType.SYMBOL_TYPE:
2620 o.description = mirror.description();
2622 case MirrorType.FUNCTION_TYPE:
2623 o.name = mirror.name();
2624 o.inferredName = mirror.inferredName();
2625 if (mirror.script()) {
2626 o.scriptId = mirror.script().id();
2629 case MirrorType.ERROR_TYPE:
2630 case MirrorType.REGEXP_TYPE:
2631 o.value = mirror.toText();
2633 case MirrorType.OBJECT_TYPE:
2634 o.className = mirror.className();
2641 JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
2643 // If serializing a reference to a mirror just return the reference and add
2644 // the mirror to the referenced mirrors.
2646 (mirror.isValue() || mirror.isScript() || mirror.isContext())) {
2647 if (this.inlineRefs_() && mirror.isValue()) {
2648 return this.serializeReferenceWithDisplayData_(mirror);
2651 return {'ref' : mirror.handle()};
2655 // Collect the JSON property/value pairs.
2658 // Add the mirror handle.
2659 if (mirror.isValue() || mirror.isScript() || mirror.isContext()) {
2660 content.handle = mirror.handle();
2663 // Always add the type.
2664 content.type = mirror.type();
2666 switch (mirror.type()) {
2667 case MirrorType.UNDEFINED_TYPE:
2668 case MirrorType.NULL_TYPE:
2669 // Undefined and null are represented just by their type.
2672 case MirrorType.BOOLEAN_TYPE:
2673 // Boolean values are simply represented by their value.
2674 content.value = mirror.value();
2677 case MirrorType.NUMBER_TYPE:
2678 // Number values are simply represented by their value.
2679 content.value = NumberToJSON_(mirror.value());
2682 case MirrorType.STRING_TYPE:
2683 // String values might have their value cropped to keep down size.
2684 if (this.maxStringLength_() != -1 &&
2685 mirror.length() > this.maxStringLength_()) {
2686 var str = mirror.getTruncatedValue(this.maxStringLength_());
2687 content.value = str;
2688 content.fromIndex = 0;
2689 content.toIndex = this.maxStringLength_();
2691 content.value = mirror.value();
2693 content.length = mirror.length();
2696 case MirrorType.SYMBOL_TYPE:
2697 content.description = mirror.description();
2700 case MirrorType.OBJECT_TYPE:
2701 case MirrorType.FUNCTION_TYPE:
2702 case MirrorType.ERROR_TYPE:
2703 case MirrorType.REGEXP_TYPE:
2704 case MirrorType.PROMISE_TYPE:
2705 case MirrorType.GENERATOR_TYPE:
2706 // Add object representation.
2707 this.serializeObject_(mirror, content, details);
2710 case MirrorType.PROPERTY_TYPE:
2711 case MirrorType.INTERNAL_PROPERTY_TYPE:
2712 throw MakeError(kDebugger,
2713 'PropertyMirror cannot be serialized independently');
2716 case MirrorType.FRAME_TYPE:
2717 // Add object representation.
2718 this.serializeFrame_(mirror, content);
2721 case MirrorType.SCOPE_TYPE:
2722 // Add object representation.
2723 this.serializeScope_(mirror, content);
2726 case MirrorType.SCRIPT_TYPE:
2727 // Script is represented by id, name and source attributes.
2728 if (mirror.name()) {
2729 content.name = mirror.name();
2731 content.id = mirror.id();
2732 content.lineOffset = mirror.lineOffset();
2733 content.columnOffset = mirror.columnOffset();
2734 content.lineCount = mirror.lineCount();
2735 if (mirror.data()) {
2736 content.data = mirror.data();
2738 if (this.includeSource_()) {
2739 content.source = mirror.source();
2741 var sourceStart = mirror.source().substring(0, 80);
2742 content.sourceStart = sourceStart;
2744 content.sourceLength = mirror.source().length;
2745 content.scriptType = mirror.scriptType();
2746 content.compilationType = mirror.compilationType();
2747 // For compilation type eval emit information on the script from which
2748 // eval was called if a script is present.
2749 if (mirror.compilationType() == 1 &&
2750 mirror.evalFromScript()) {
2751 content.evalFromScript =
2752 this.serializeReference(mirror.evalFromScript());
2753 var evalFromLocation = mirror.evalFromLocation();
2754 if (evalFromLocation) {
2755 content.evalFromLocation = { line: evalFromLocation.line,
2756 column: evalFromLocation.column };
2758 if (mirror.evalFromFunctionName()) {
2759 content.evalFromFunctionName = mirror.evalFromFunctionName();
2762 if (mirror.context()) {
2763 content.context = this.serializeReference(mirror.context());
2767 case MirrorType.CONTEXT_TYPE:
2768 content.data = mirror.data();
2772 // Always add the text representation.
2773 content.text = mirror.toText();
2775 // Create and return the JSON string.
2781 * Serialize object information to the following JSON format.
2783 * {"className":"<class name>",
2784 * "constructorFunction":{"ref":<number>},
2785 * "protoObject":{"ref":<number>},
2786 * "prototypeObject":{"ref":<number>},
2787 * "namedInterceptor":<boolean>,
2788 * "indexedInterceptor":<boolean>,
2789 * "properties":[<properties>],
2790 * "internalProperties":[<internal properties>]}
2792 JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
2794 // Add general object properties.
2795 content.className = mirror.className();
2796 content.constructorFunction =
2797 this.serializeReference(mirror.constructorFunction());
2798 content.protoObject = this.serializeReference(mirror.protoObject());
2799 content.prototypeObject = this.serializeReference(mirror.prototypeObject());
2801 // Add flags to indicate whether there are interceptors.
2802 if (mirror.hasNamedInterceptor()) {
2803 content.namedInterceptor = true;
2805 if (mirror.hasIndexedInterceptor()) {
2806 content.indexedInterceptor = true;
2809 if (mirror.isFunction()) {
2810 // Add function specific properties.
2811 content.name = mirror.name();
2812 if (!IS_UNDEFINED(mirror.inferredName())) {
2813 content.inferredName = mirror.inferredName();
2815 content.resolved = mirror.resolved();
2816 if (mirror.resolved()) {
2817 content.source = mirror.source();
2819 if (mirror.script()) {
2820 content.script = this.serializeReference(mirror.script());
2821 content.scriptId = mirror.script().id();
2823 serializeLocationFields(mirror.sourceLocation(), content);
2826 content.scopes = [];
2827 for (var i = 0; i < mirror.scopeCount(); i++) {
2828 var scope = mirror.scope(i);
2829 content.scopes.push({
2830 type: scope.scopeType(),
2836 if (mirror.isGenerator()) {
2837 // Add generator specific properties.
2839 // Either 'running', 'closed', or 'suspended'.
2840 content.status = mirror.status();
2842 content.func = this.serializeReference(mirror.func())
2843 content.receiver = this.serializeReference(mirror.receiver())
2845 // If the generator is suspended, the content add line/column properties.
2846 serializeLocationFields(mirror.sourceLocation(), content);
2848 // TODO(wingo): Also serialize a reference to the context (scope chain).
2851 if (mirror.isDate()) {
2852 // Add date specific properties.
2853 content.value = mirror.value();
2856 if (mirror.isPromise()) {
2857 // Add promise specific properties.
2858 content.status = mirror.status();
2859 content.promiseValue = this.serializeReference(mirror.promiseValue());
2862 // Add actual properties - named properties followed by indexed properties.
2863 var propertyNames = mirror.propertyNames(PropertyKind.Named);
2864 var propertyIndexes = mirror.propertyNames(PropertyKind.Indexed);
2865 var p = new GlobalArray(propertyNames.length + propertyIndexes.length);
2866 for (var i = 0; i < propertyNames.length; i++) {
2867 var propertyMirror = mirror.property(propertyNames[i]);
2868 p[i] = this.serializeProperty_(propertyMirror);
2870 this.add_(propertyMirror.value());
2873 for (var i = 0; i < propertyIndexes.length; i++) {
2874 var propertyMirror = mirror.property(propertyIndexes[i]);
2875 p[propertyNames.length + i] = this.serializeProperty_(propertyMirror);
2877 this.add_(propertyMirror.value());
2880 content.properties = p;
2882 var internalProperties = mirror.internalProperties();
2883 if (internalProperties.length > 0) {
2885 for (var i = 0; i < internalProperties.length; i++) {
2886 ip.push(this.serializeInternalProperty_(internalProperties[i]));
2888 content.internalProperties = ip;
2894 * Serialize location information to the following JSON format:
2896 * "position":"<position>",
2898 * "column":"<column>",
2900 * @param {SourceLocation} location The location to serialize, may be undefined.
2902 function serializeLocationFields (location, content) {
2906 content.position = location.position;
2907 var line = location.line;
2908 if (!IS_UNDEFINED(line)) {
2909 content.line = line;
2911 var column = location.column;
2912 if (!IS_UNDEFINED(column)) {
2913 content.column = column;
2919 * Serialize property information to the following JSON format for building the
2920 * array of properties.
2922 * {"name":"<property name>",
2923 * "attributes":<number>,
2924 * "propertyType":<number>,
2927 * If the attribute for the property is PropertyAttribute.None it is not added.
2928 * Here are a couple of examples.
2930 * {"name":"hello","propertyType":0,"ref":1}
2931 * {"name":"length","attributes":7,"propertyType":3,"ref":2}
2933 * @param {PropertyMirror} propertyMirror The property to serialize.
2934 * @returns {Object} Protocol object representing the property.
2936 JSONProtocolSerializer.prototype.serializeProperty_ = function(propertyMirror) {
2939 result.name = propertyMirror.name();
2940 var propertyValue = propertyMirror.value();
2941 if (this.inlineRefs_() && propertyValue.isValue()) {
2942 result.value = this.serializeReferenceWithDisplayData_(propertyValue);
2944 if (propertyMirror.attributes() != PropertyAttribute.None) {
2945 result.attributes = propertyMirror.attributes();
2947 result.propertyType = propertyMirror.propertyType();
2948 result.ref = propertyValue.handle();
2955 * Serialize internal property information to the following JSON format for
2956 * building the array of properties.
2958 * {"name":"<property name>",
2961 * {"name":"[[BoundThis]]","ref":117}
2963 * @param {InternalPropertyMirror} propertyMirror The property to serialize.
2964 * @returns {Object} Protocol object representing the property.
2966 JSONProtocolSerializer.prototype.serializeInternalProperty_ =
2967 function(propertyMirror) {
2970 result.name = propertyMirror.name();
2971 var propertyValue = propertyMirror.value();
2972 if (this.inlineRefs_() && propertyValue.isValue()) {
2973 result.value = this.serializeReferenceWithDisplayData_(propertyValue);
2975 result.ref = propertyValue.handle();
2981 JSONProtocolSerializer.prototype.serializeFrame_ = function(mirror, content) {
2982 content.index = mirror.index();
2983 content.receiver = this.serializeReference(mirror.receiver());
2984 var func = mirror.func();
2985 content.func = this.serializeReference(func);
2986 var script = func.script();
2988 content.script = this.serializeReference(script);
2990 content.constructCall = mirror.isConstructCall();
2991 content.atReturn = mirror.isAtReturn();
2992 if (mirror.isAtReturn()) {
2993 content.returnValue = this.serializeReference(mirror.returnValue());
2995 content.debuggerFrame = mirror.isDebuggerFrame();
2996 var x = new GlobalArray(mirror.argumentCount());
2997 for (var i = 0; i < mirror.argumentCount(); i++) {
2999 var argument_name = mirror.argumentName(i);
3000 if (argument_name) {
3001 arg.name = argument_name;
3003 arg.value = this.serializeReference(mirror.argumentValue(i));
3006 content.arguments = x;
3007 var x = new GlobalArray(mirror.localCount());
3008 for (var i = 0; i < mirror.localCount(); i++) {
3010 local.name = mirror.localName(i);
3011 local.value = this.serializeReference(mirror.localValue(i));
3015 serializeLocationFields(mirror.sourceLocation(), content);
3016 var source_line_text = mirror.sourceLineText();
3017 if (!IS_UNDEFINED(source_line_text)) {
3018 content.sourceLineText = source_line_text;
3021 content.scopes = [];
3022 for (var i = 0; i < mirror.scopeCount(); i++) {
3023 var scope = mirror.scope(i);
3024 content.scopes.push({
3025 type: scope.scopeType(),
3032 JSONProtocolSerializer.prototype.serializeScope_ = function(mirror, content) {
3033 content.index = mirror.scopeIndex();
3034 content.frameIndex = mirror.frameIndex();
3035 content.type = mirror.scopeType();
3036 content.object = this.inlineRefs_() ?
3037 this.serializeValue(mirror.scopeObject()) :
3038 this.serializeReference(mirror.scopeObject());
3043 * Convert a number to a protocol value. For all finite numbers the number
3044 * itself is returned. For non finite numbers NaN, Infinite and
3045 * -Infinite the string representation "NaN", "Infinite" or "-Infinite"
3046 * (not including the quotes) is returned.
3048 * @param {number} value The number value to convert to a protocol value.
3049 * @returns {number|string} Protocol value.
3051 function NumberToJSON_(value) {
3055 if (!NUMBER_IS_FINITE(value)) {
3065 // ----------------------------------------------------------------------------
3068 utils.InstallFunctions(global, DONT_ENUM, [
3069 "MakeMirror", MakeMirror,
3070 "MakeMirrorSerializer", MakeMirrorSerializer,
3071 "LookupMirror", LookupMirror,
3072 "ToggleMirrorCache", ToggleMirrorCache,
3073 "MirrorCacheIsEmpty", MirrorCacheIsEmpty,
3076 utils.InstallConstants(global, [
3077 "ScopeType", ScopeType,
3078 "PropertyKind", PropertyKind,
3079 "PropertyType", PropertyType,
3080 "PropertyAttribute", PropertyAttribute,
3082 "ValueMirror", ValueMirror,
3083 "UndefinedMirror", UndefinedMirror,
3084 "NullMirror", NullMirror,
3085 "BooleanMirror", BooleanMirror,
3086 "NumberMirror", NumberMirror,
3087 "StringMirror", StringMirror,
3088 "SymbolMirror", SymbolMirror,
3089 "ObjectMirror", ObjectMirror,
3090 "FunctionMirror", FunctionMirror,
3091 "UnresolvedFunctionMirror", UnresolvedFunctionMirror,
3092 "ArrayMirror", ArrayMirror,
3093 "DateMirror", DateMirror,
3094 "RegExpMirror", RegExpMirror,
3095 "ErrorMirror", ErrorMirror,
3096 "PromiseMirror", PromiseMirror,
3097 "MapMirror", MapMirror,
3098 "SetMirror", SetMirror,
3099 "IteratorMirror", IteratorMirror,
3100 "GeneratorMirror", GeneratorMirror,
3101 "PropertyMirror", PropertyMirror,
3102 "InternalPropertyMirror", InternalPropertyMirror,
3103 "FrameMirror", FrameMirror,
3104 "ScriptMirror", ScriptMirror,
3105 "ScopeMirror", ScopeMirror,
3106 "FrameDetails", FrameDetails,
3109 // Functions needed by the debugger runtime.
3110 utils.InstallFunctions(utils, DONT_ENUM, [
3111 "ClearMirrorCache", ClearMirrorCache
3114 // Export to debug.js
3115 utils.Export(function(to) {
3116 to.MirrorType = MirrorType;