blob: 94e616a7f53028e415bb3291ea2d13f77eca8092 [file] [log] [blame]
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001// Copyright 2006-2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
ager@chromium.orgeadaf222009-06-16 09:43:10 +000028// Handle id counters.
ager@chromium.org32912102009-01-16 10:38:43 +000029var next_handle_ = 0;
ager@chromium.orgeadaf222009-06-16 09:43:10 +000030var next_transient_handle_ = -1;
31
32// Mirror cache.
ager@chromium.org32912102009-01-16 10:38:43 +000033var mirror_cache_ = [];
34
ager@chromium.orgeadaf222009-06-16 09:43:10 +000035
ager@chromium.org32912102009-01-16 10:38:43 +000036/**
37 * Clear the mirror handle cache.
38 */
39function ClearMirrorCache() {
40 next_handle_ = 0;
41 mirror_cache_ = [];
42}
43
44
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +000045/**
46 * Returns the mirror for a specified value or object.
47 *
48 * @param {value or Object} value the value or object to retreive the mirror for
ager@chromium.orgeadaf222009-06-16 09:43:10 +000049 * @param {boolean} transient indicate whether this object is transient and
50 * should not be added to the mirror cache. The default is not transient.
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +000051 * @returns {Mirror} the mirror reflects the passed value or object
52 */
ager@chromium.orgeadaf222009-06-16 09:43:10 +000053function MakeMirror(value, opt_transient) {
ager@chromium.org32912102009-01-16 10:38:43 +000054 var mirror;
ager@chromium.orgeadaf222009-06-16 09:43:10 +000055
56 // Look for non transient mirrors in the mirror cache.
57 if (!opt_transient) {
58 for (id in mirror_cache_) {
59 mirror = mirror_cache_[id];
60 if (mirror.value() === value) {
61 return mirror;
62 }
63 // Special check for NaN as NaN == NaN is false.
64 if (mirror.isNumber() && isNaN(mirror.value()) &&
65 typeof value == 'number' && isNaN(value)) {
66 return mirror;
67 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +000068 }
ager@chromium.org32912102009-01-16 10:38:43 +000069 }
lrn@chromium.org25156de2010-04-06 13:10:27 +000070
ager@chromium.org32912102009-01-16 10:38:43 +000071 if (IS_UNDEFINED(value)) {
72 mirror = new UndefinedMirror();
73 } else if (IS_NULL(value)) {
74 mirror = new NullMirror();
75 } else if (IS_BOOLEAN(value)) {
76 mirror = new BooleanMirror(value);
77 } else if (IS_NUMBER(value)) {
78 mirror = new NumberMirror(value);
79 } else if (IS_STRING(value)) {
80 mirror = new StringMirror(value);
81 } else if (IS_ARRAY(value)) {
82 mirror = new ArrayMirror(value);
83 } else if (IS_DATE(value)) {
84 mirror = new DateMirror(value);
85 } else if (IS_FUNCTION(value)) {
86 mirror = new FunctionMirror(value);
87 } else if (IS_REGEXP(value)) {
88 mirror = new RegExpMirror(value);
89 } else if (IS_ERROR(value)) {
90 mirror = new ErrorMirror(value);
iposva@chromium.org245aa852009-02-10 00:49:54 +000091 } else if (IS_SCRIPT(value)) {
92 mirror = new ScriptMirror(value);
ager@chromium.org32912102009-01-16 10:38:43 +000093 } else {
ager@chromium.orgeadaf222009-06-16 09:43:10 +000094 mirror = new ObjectMirror(value, OBJECT_TYPE, opt_transient);
ager@chromium.org32912102009-01-16 10:38:43 +000095 }
96
97 mirror_cache_[mirror.handle()] = mirror;
98 return mirror;
99}
100
101
102/**
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000103 * Returns the mirror for a specified mirror handle.
104 *
105 * @param {number} handle the handle to find the mirror for
106 * @returns {Mirror or undefiend} the mirror with the requested handle or
107 * undefined if no mirror with the requested handle was found
108 */
109function LookupMirror(handle) {
110 return mirror_cache_[handle];
111}
112
lrn@chromium.org25156de2010-04-06 13:10:27 +0000113
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000114/**
ager@chromium.org32912102009-01-16 10:38:43 +0000115 * Returns the mirror for the undefined value.
116 *
117 * @returns {Mirror} the mirror reflects the undefined value
118 */
119function GetUndefinedMirror() {
120 return MakeMirror(void 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000121}
122
123
124/**
125 * Inherit the prototype methods from one constructor into another.
126 *
127 * The Function.prototype.inherits from lang.js rewritten as a standalone
128 * function (not on Function.prototype). NOTE: If this file is to be loaded
129 * during bootstrapping this function needs to be revritten using some native
130 * functions as prototype setup using normal JavaScript does not work as
131 * expected during bootstrapping (see mirror.js in r114903).
132 *
133 * @param {function} ctor Constructor function which needs to inherit the
134 * prototype
135 * @param {function} superCtor Constructor function to inherit prototype from
136 */
137function inherits(ctor, superCtor) {
138 var tempCtor = function(){};
139 tempCtor.prototype = superCtor.prototype;
140 ctor.super_ = superCtor.prototype;
141 ctor.prototype = new tempCtor();
142 ctor.prototype.constructor = ctor;
143}
144
145
146// Type names of the different mirrors.
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000147var UNDEFINED_TYPE = 'undefined';
148var NULL_TYPE = 'null';
149var BOOLEAN_TYPE = 'boolean';
150var NUMBER_TYPE = 'number';
151var STRING_TYPE = 'string';
152var OBJECT_TYPE = 'object';
153var FUNCTION_TYPE = 'function';
154var REGEXP_TYPE = 'regexp';
155var ERROR_TYPE = 'error';
156var PROPERTY_TYPE = 'property';
157var FRAME_TYPE = 'frame';
158var SCRIPT_TYPE = 'script';
159var CONTEXT_TYPE = 'context';
160var SCOPE_TYPE = 'scope';
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000161
162// Maximum length when sending strings through the JSON protocol.
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000163var kMaxProtocolStringLength = 80;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000164
165// Different kind of properties.
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000166var PropertyKind = {};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167PropertyKind.Named = 1;
168PropertyKind.Indexed = 2;
169
170
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000171// A copy of the PropertyType enum from global.h
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000172var PropertyType = {};
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000173PropertyType.Normal = 0;
174PropertyType.Field = 1;
175PropertyType.ConstantFunction = 2;
176PropertyType.Callbacks = 3;
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000177PropertyType.Handler = 4;
178PropertyType.Interceptor = 5;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000179PropertyType.Transition = 6;
180PropertyType.Nonexistent = 7;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000181
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000182
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000183// Different attributes for a property.
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000184var PropertyAttribute = {};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000185PropertyAttribute.None = NONE;
186PropertyAttribute.ReadOnly = READ_ONLY;
187PropertyAttribute.DontEnum = DONT_ENUM;
188PropertyAttribute.DontDelete = DONT_DELETE;
189
190
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000191// A copy of the scope types from runtime.cc.
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000192var ScopeType = { Global: 0,
193 Local: 1,
194 With: 2,
195 Closure: 3,
196 Catch: 4,
197 Block: 5 };
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000198
199
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000200// Mirror hierarchy:
201// - Mirror
202// - ValueMirror
203// - UndefinedMirror
204// - NullMirror
205// - NumberMirror
206// - StringMirror
207// - ObjectMirror
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +0000208// - FunctionMirror
209// - UnresolvedFunctionMirror
210// - ArrayMirror
211// - DateMirror
212// - RegExpMirror
213// - ErrorMirror
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214// - PropertyMirror
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000215// - FrameMirror
216// - ScriptMirror
217
218
219/**
220 * Base class for all mirror objects.
221 * @param {string} type The type of the mirror
222 * @constructor
223 */
224function Mirror(type) {
225 this.type_ = type;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000226}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000227
228
229Mirror.prototype.type = function() {
230 return this.type_;
231};
232
233
234/**
ager@chromium.org32912102009-01-16 10:38:43 +0000235 * Check whether the mirror reflects a value.
236 * @returns {boolean} True if the mirror reflects a value.
237 */
238Mirror.prototype.isValue = function() {
239 return this instanceof ValueMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000240};
ager@chromium.org32912102009-01-16 10:38:43 +0000241
242
243/**
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000244 * Check whether the mirror reflects the undefined value.
245 * @returns {boolean} True if the mirror reflects the undefined value.
246 */
247Mirror.prototype.isUndefined = function() {
248 return this instanceof UndefinedMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000249};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000250
251
252/**
253 * Check whether the mirror reflects the null value.
254 * @returns {boolean} True if the mirror reflects the null value
255 */
256Mirror.prototype.isNull = function() {
257 return this instanceof NullMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000258};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000259
260
261/**
262 * Check whether the mirror reflects a boolean value.
263 * @returns {boolean} True if the mirror reflects a boolean value
264 */
265Mirror.prototype.isBoolean = function() {
266 return this instanceof BooleanMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000267};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268
269
270/**
271 * Check whether the mirror reflects a number value.
272 * @returns {boolean} True if the mirror reflects a number value
273 */
274Mirror.prototype.isNumber = function() {
275 return this instanceof NumberMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000276};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000277
278
279/**
280 * Check whether the mirror reflects a string value.
281 * @returns {boolean} True if the mirror reflects a string value
282 */
283Mirror.prototype.isString = function() {
284 return this instanceof StringMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000285};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000286
287
288/**
289 * Check whether the mirror reflects an object.
290 * @returns {boolean} True if the mirror reflects an object
291 */
292Mirror.prototype.isObject = function() {
293 return this instanceof ObjectMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000294};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000295
296
297/**
298 * Check whether the mirror reflects a function.
299 * @returns {boolean} True if the mirror reflects a function
300 */
301Mirror.prototype.isFunction = function() {
302 return this instanceof FunctionMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000303};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000304
305
306/**
307 * Check whether the mirror reflects an unresolved function.
308 * @returns {boolean} True if the mirror reflects an unresolved function
309 */
310Mirror.prototype.isUnresolvedFunction = function() {
311 return this instanceof UnresolvedFunctionMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000312};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000313
314
315/**
316 * Check whether the mirror reflects an array.
317 * @returns {boolean} True if the mirror reflects an array
318 */
319Mirror.prototype.isArray = function() {
320 return this instanceof ArrayMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000321};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000322
323
324/**
325 * Check whether the mirror reflects a date.
326 * @returns {boolean} True if the mirror reflects a date
327 */
328Mirror.prototype.isDate = function() {
329 return this instanceof DateMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000330};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000331
332
333/**
334 * Check whether the mirror reflects a regular expression.
335 * @returns {boolean} True if the mirror reflects a regular expression
336 */
337Mirror.prototype.isRegExp = function() {
338 return this instanceof RegExpMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000339};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000340
341
342/**
343 * Check whether the mirror reflects an error.
344 * @returns {boolean} True if the mirror reflects an error
345 */
346Mirror.prototype.isError = function() {
347 return this instanceof ErrorMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000348};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000349
350
351/**
352 * Check whether the mirror reflects a property.
353 * @returns {boolean} True if the mirror reflects a property
354 */
355Mirror.prototype.isProperty = function() {
356 return this instanceof PropertyMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000357};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000358
359
360/**
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000361 * Check whether the mirror reflects a stack frame.
362 * @returns {boolean} True if the mirror reflects a stack frame
363 */
364Mirror.prototype.isFrame = function() {
365 return this instanceof FrameMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000366};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000367
368
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +0000369/**
370 * Check whether the mirror reflects a script.
371 * @returns {boolean} True if the mirror reflects a script
372 */
373Mirror.prototype.isScript = function() {
374 return this instanceof ScriptMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000375};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000376
377
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000378/**
ager@chromium.org9085a012009-05-11 19:22:57 +0000379 * Check whether the mirror reflects a context.
380 * @returns {boolean} True if the mirror reflects a context
381 */
382Mirror.prototype.isContext = function() {
383 return this instanceof ContextMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000384};
ager@chromium.org9085a012009-05-11 19:22:57 +0000385
386
387/**
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000388 * Check whether the mirror reflects a scope.
389 * @returns {boolean} True if the mirror reflects a scope
390 */
391Mirror.prototype.isScope = function() {
392 return this instanceof ScopeMirror;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000393};
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000394
395
396/**
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000397 * Allocate a handle id for this object.
398 */
399Mirror.prototype.allocateHandle_ = function() {
400 this.handle_ = next_handle_++;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000401};
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000402
403
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000404/**
405 * Allocate a transient handle id for this object. Transient handles are
406 * negative.
407 */
408Mirror.prototype.allocateTransientHandle_ = function() {
409 this.handle_ = next_transient_handle_--;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000410};
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000411
412
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000413Mirror.prototype.toText = function() {
414 // Simpel to text which is used when on specialization in subclass.
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000415 return "#<" + this.constructor.name + ">";
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000416};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000417
418
419/**
420 * Base class for all value mirror objects.
421 * @param {string} type The type of the mirror
422 * @param {value} value The value reflected by this mirror
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000423 * @param {boolean} transient indicate whether this object is transient with a
424 * transient handle
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000425 * @constructor
426 * @extends Mirror
427 */
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000428function ValueMirror(type, value, transient) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000429 %_CallFunction(this, type, Mirror);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000430 this.value_ = value;
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000431 if (!transient) {
432 this.allocateHandle_();
433 } else {
434 this.allocateTransientHandle_();
435 }
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000436}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000437inherits(ValueMirror, Mirror);
438
439
ager@chromium.org32912102009-01-16 10:38:43 +0000440Mirror.prototype.handle = function() {
441 return this.handle_;
442};
443
444
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000445/**
446 * Check whether this is a primitive value.
447 * @return {boolean} True if the mirror reflects a primitive value
448 */
449ValueMirror.prototype.isPrimitive = function() {
450 var type = this.type();
451 return type === 'undefined' ||
452 type === 'null' ||
453 type === 'boolean' ||
454 type === 'number' ||
455 type === 'string';
456};
457
458
ager@chromium.org32912102009-01-16 10:38:43 +0000459/**
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000460 * Get the actual value reflected by this mirror.
461 * @return {value} The value reflected by this mirror
462 */
463ValueMirror.prototype.value = function() {
464 return this.value_;
465};
466
467
468/**
469 * Mirror object for Undefined.
470 * @constructor
471 * @extends ValueMirror
472 */
473function UndefinedMirror() {
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000474 %_CallFunction(this, UNDEFINED_TYPE, void 0, ValueMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000475}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476inherits(UndefinedMirror, ValueMirror);
477
478
479UndefinedMirror.prototype.toText = function() {
480 return 'undefined';
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000481};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000482
483
484/**
485 * Mirror object for null.
486 * @constructor
487 * @extends ValueMirror
488 */
489function NullMirror() {
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000490 %_CallFunction(this, NULL_TYPE, null, ValueMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000491}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000492inherits(NullMirror, ValueMirror);
493
494
495NullMirror.prototype.toText = function() {
496 return 'null';
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000497};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498
499
500/**
501 * Mirror object for boolean values.
502 * @param {boolean} value The boolean value reflected by this mirror
503 * @constructor
504 * @extends ValueMirror
505 */
506function BooleanMirror(value) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000507 %_CallFunction(this, BOOLEAN_TYPE, value, ValueMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000508}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000509inherits(BooleanMirror, ValueMirror);
510
511
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000512BooleanMirror.prototype.toText = function() {
513 return this.value_ ? 'true' : 'false';
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000514};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000515
516
517/**
518 * Mirror object for number values.
519 * @param {number} value The number value reflected by this mirror
520 * @constructor
521 * @extends ValueMirror
522 */
523function NumberMirror(value) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000524 %_CallFunction(this, NUMBER_TYPE, value, ValueMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000525}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000526inherits(NumberMirror, ValueMirror);
527
528
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000529NumberMirror.prototype.toText = function() {
530 return %NumberToString(this.value_);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000531};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000532
533
534/**
535 * Mirror object for string values.
536 * @param {string} value The string value reflected by this mirror
537 * @constructor
538 * @extends ValueMirror
539 */
540function StringMirror(value) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000541 %_CallFunction(this, STRING_TYPE, value, ValueMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000542}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000543inherits(StringMirror, ValueMirror);
544
545
546StringMirror.prototype.length = function() {
547 return this.value_.length;
548};
549
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +0000550StringMirror.prototype.getTruncatedValue = function(maxLength) {
551 if (maxLength != -1 && this.length() > maxLength) {
552 return this.value_.substring(0, maxLength) +
553 '... (length: ' + this.length() + ')';
554 }
555 return this.value_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000556};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000557
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000558StringMirror.prototype.toText = function() {
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +0000559 return this.getTruncatedValue(kMaxProtocolStringLength);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000560};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000561
562
563/**
564 * Mirror object for objects.
565 * @param {object} value The object reflected by this mirror
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000566 * @param {boolean} transient indicate whether this object is transient with a
567 * transient handle
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568 * @constructor
569 * @extends ValueMirror
570 */
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000571function ObjectMirror(value, type, transient) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000572 %_CallFunction(this, type || OBJECT_TYPE, value, transient, ValueMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000573}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000574inherits(ObjectMirror, ValueMirror);
575
576
577ObjectMirror.prototype.className = function() {
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000578 return %_ClassOf(this.value_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000579};
580
581
582ObjectMirror.prototype.constructorFunction = function() {
583 return MakeMirror(%DebugGetProperty(this.value_, 'constructor'));
584};
585
586
587ObjectMirror.prototype.prototypeObject = function() {
588 return MakeMirror(%DebugGetProperty(this.value_, 'prototype'));
589};
590
591
592ObjectMirror.prototype.protoObject = function() {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000593 return MakeMirror(%DebugGetPrototype(this.value_));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000594};
595
596
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +0000597/**
598 * Return the primitive value if this is object of Boolean, Number or String
599 * type (but not Date). Otherwise return undefined.
600 */
601ObjectMirror.prototype.primitiveValue = function() {
602 if (!IS_STRING_WRAPPER(this.value_) && !IS_NUMBER_WRAPPER(this.value_) &&
603 !IS_BOOLEAN_WRAPPER(this.value_)) {
604 return void 0;
605 }
606 var primitiveValue = %_ValueOf(this.value_);
607 if (IS_UNDEFINED(primitiveValue)) {
608 return void 0;
609 }
610 return MakeMirror(primitiveValue);
611};
612
613
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000614ObjectMirror.prototype.hasNamedInterceptor = function() {
615 // Get information on interceptors for this object.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000616 var x = %GetInterceptorInfo(this.value_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000617 return (x & 2) != 0;
618};
619
620
621ObjectMirror.prototype.hasIndexedInterceptor = function() {
622 // Get information on interceptors for this object.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000623 var x = %GetInterceptorInfo(this.value_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000624 return (x & 1) != 0;
625};
626
627
628/**
629 * Return the property names for this object.
630 * @param {number} kind Indicate whether named, indexed or both kinds of
631 * properties are requested
632 * @param {number} limit Limit the number of names returend to the specified
633 value
634 * @return {Array} Property names for this object
635 */
636ObjectMirror.prototype.propertyNames = function(kind, limit) {
637 // Find kind and limit and allocate array for the result
638 kind = kind || PropertyKind.Named | PropertyKind.Indexed;
639
640 var propertyNames;
641 var elementNames;
642 var total = 0;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000643
ager@chromium.org32912102009-01-16 10:38:43 +0000644 // Find all the named properties.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645 if (kind & PropertyKind.Named) {
ager@chromium.org32912102009-01-16 10:38:43 +0000646 // Get the local property names.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000647 propertyNames = %GetLocalPropertyNames(this.value_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000648 total += propertyNames.length;
ager@chromium.org32912102009-01-16 10:38:43 +0000649
650 // Get names for named interceptor properties if any.
651 if (this.hasNamedInterceptor() && (kind & PropertyKind.Named)) {
652 var namedInterceptorNames =
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000653 %GetNamedInterceptorPropertyNames(this.value_);
ager@chromium.org32912102009-01-16 10:38:43 +0000654 if (namedInterceptorNames) {
655 propertyNames = propertyNames.concat(namedInterceptorNames);
656 total += namedInterceptorNames.length;
657 }
658 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000659 }
ager@chromium.org32912102009-01-16 10:38:43 +0000660
661 // Find all the indexed properties.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000662 if (kind & PropertyKind.Indexed) {
ager@chromium.org32912102009-01-16 10:38:43 +0000663 // Get the local element names.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000664 elementNames = %GetLocalElementNames(this.value_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000665 total += elementNames.length;
ager@chromium.org32912102009-01-16 10:38:43 +0000666
667 // Get names for indexed interceptor properties.
668 if (this.hasIndexedInterceptor() && (kind & PropertyKind.Indexed)) {
669 var indexedInterceptorNames =
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000670 %GetIndexedInterceptorElementNames(this.value_);
ager@chromium.org32912102009-01-16 10:38:43 +0000671 if (indexedInterceptorNames) {
672 elementNames = elementNames.concat(indexedInterceptorNames);
673 total += indexedInterceptorNames.length;
674 }
675 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000676 }
677 limit = Math.min(limit || total, total);
678
679 var names = new Array(limit);
680 var index = 0;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000681
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000682 // Copy names for named properties.
683 if (kind & PropertyKind.Named) {
684 for (var i = 0; index < limit && i < propertyNames.length; i++) {
685 names[index++] = propertyNames[i];
686 }
687 }
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000688
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000689 // Copy names for indexed properties.
690 if (kind & PropertyKind.Indexed) {
691 for (var i = 0; index < limit && i < elementNames.length; i++) {
692 names[index++] = elementNames[i];
693 }
694 }
695
696 return names;
697};
698
699
700/**
701 * Return the properties for this object as an array of PropertyMirror objects.
702 * @param {number} kind Indicate whether named, indexed or both kinds of
703 * properties are requested
704 * @param {number} limit Limit the number of properties returend to the
705 specified value
706 * @return {Array} Property mirrors for this object
707 */
708ObjectMirror.prototype.properties = function(kind, limit) {
709 var names = this.propertyNames(kind, limit);
710 var properties = new Array(names.length);
711 for (var i = 0; i < names.length; i++) {
712 properties[i] = this.property(names[i]);
713 }
714
715 return properties;
716};
717
718
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000719ObjectMirror.prototype.property = function(name) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000720 var details = %DebugGetPropertyDetails(this.value_, %ToString(name));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721 if (details) {
ager@chromium.org32912102009-01-16 10:38:43 +0000722 return new PropertyMirror(this, name, details);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000723 }
724
725 // Nothing found.
ager@chromium.org32912102009-01-16 10:38:43 +0000726 return GetUndefinedMirror();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000727};
728
729
730
731/**
732 * Try to find a property from its value.
733 * @param {Mirror} value The property value to look for
734 * @return {PropertyMirror} The property with the specified value. If no
735 * property was found with the specified value UndefinedMirror is returned
736 */
737ObjectMirror.prototype.lookupProperty = function(value) {
738 var properties = this.properties();
739
740 // Look for property value in properties.
741 for (var i = 0; i < properties.length; i++) {
742
743 // Skip properties which are defined through assessors.
744 var property = properties[i];
745 if (property.propertyType() != PropertyType.Callbacks) {
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000746 if (%_ObjectEquals(property.value_, value.value_)) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000747 return property;
748 }
749 }
750 }
751
752 // Nothing found.
ager@chromium.org32912102009-01-16 10:38:43 +0000753 return GetUndefinedMirror();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000754};
755
756
757/**
758 * Returns objects which has direct references to this object
iposva@chromium.org245aa852009-02-10 00:49:54 +0000759 * @param {number} opt_max_objects Optional parameter specifying the maximum
760 * number of referencing objects to return.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000761 * @return {Array} The objects which has direct references to this object.
762 */
iposva@chromium.org245aa852009-02-10 00:49:54 +0000763ObjectMirror.prototype.referencedBy = function(opt_max_objects) {
764 // Find all objects with direct references to this object.
765 var result = %DebugReferencedBy(this.value_,
766 Mirror.prototype, opt_max_objects || 0);
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000767
iposva@chromium.org245aa852009-02-10 00:49:54 +0000768 // Make mirrors for all the references found.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000769 for (var i = 0; i < result.length; i++) {
770 result[i] = MakeMirror(result[i]);
771 }
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000772
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000773 return result;
774};
775
776
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777ObjectMirror.prototype.toText = function() {
778 var name;
779 var ctor = this.constructorFunction();
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000780 if (!ctor.isFunction()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000781 name = this.className();
782 } else {
783 name = ctor.name();
784 if (!name) {
785 name = this.className();
786 }
787 }
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000788 return '#<' + name + '>';
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000789};
790
791
792/**
793 * Mirror object for functions.
794 * @param {function} value The function object reflected by this mirror.
795 * @constructor
796 * @extends ObjectMirror
797 */
798function FunctionMirror(value) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000799 %_CallFunction(this, value, FUNCTION_TYPE, ObjectMirror);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000800 this.resolved_ = true;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000801}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000802inherits(FunctionMirror, ObjectMirror);
803
804
805/**
806 * Returns whether the function is resolved.
807 * @return {boolean} True if the function is resolved. Unresolved functions can
808 * only originate as functions from stack frames
809 */
810FunctionMirror.prototype.resolved = function() {
811 return this.resolved_;
812};
813
814
815/**
816 * Returns the name of the function.
817 * @return {string} Name of the function
818 */
819FunctionMirror.prototype.name = function() {
820 return %FunctionGetName(this.value_);
821};
822
823
824/**
ager@chromium.org9085a012009-05-11 19:22:57 +0000825 * Returns the inferred name of the function.
826 * @return {string} Name of the function
827 */
828FunctionMirror.prototype.inferredName = function() {
829 return %FunctionGetInferredName(this.value_);
830};
831
832
833/**
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000834 * Returns the source code for the function.
835 * @return {string or undefined} The source code for the function. If the
836 * function is not resolved undefined will be returned.
837 */
838FunctionMirror.prototype.source = function() {
839 // Return source if function is resolved. Otherwise just fall through to
840 // return undefined.
841 if (this.resolved()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000842 return builtins.FunctionSourceString(this.value_);
843 }
844};
845
846
847/**
848 * Returns the script object for the function.
849 * @return {ScriptMirror or undefined} Script object for the function or
850 * undefined if the function has no script
851 */
852FunctionMirror.prototype.script = function() {
853 // Return script if function is resolved. Otherwise just fall through
854 // to return undefined.
855 if (this.resolved()) {
856 var script = %FunctionGetScript(this.value_);
857 if (script) {
iposva@chromium.org245aa852009-02-10 00:49:54 +0000858 return MakeMirror(script);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000859 }
860 }
861};
862
863
864/**
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000865 * Returns the script source position for the function. Only makes sense
866 * for functions which has a script defined.
867 * @return {Number or undefined} in-script position for the function
868 */
869FunctionMirror.prototype.sourcePosition_ = function() {
870 // Return script if function is resolved. Otherwise just fall through
871 // to return undefined.
872 if (this.resolved()) {
873 return %FunctionGetScriptSourcePosition(this.value_);
874 }
875};
876
877
878/**
879 * Returns the script source location object for the function. Only makes sense
880 * for functions which has a script defined.
881 * @return {Location or undefined} in-script location for the function begin
882 */
883FunctionMirror.prototype.sourceLocation = function() {
884 if (this.resolved() && this.script()) {
885 return this.script().locationFromPosition(this.sourcePosition_(),
886 true);
887 }
888};
889
890
891/**
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000892 * Returns objects constructed by this function.
893 * @param {number} opt_max_instances Optional parameter specifying the maximum
894 * number of instances to return.
895 * @return {Array or undefined} The objects constructed by this function.
896 */
897FunctionMirror.prototype.constructedBy = function(opt_max_instances) {
898 if (this.resolved()) {
899 // Find all objects constructed from this function.
900 var result = %DebugConstructedBy(this.value_, opt_max_instances || 0);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000901
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000902 // Make mirrors for all the instances found.
903 for (var i = 0; i < result.length; i++) {
904 result[i] = MakeMirror(result[i]);
905 }
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000906
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000907 return result;
908 } else {
909 return [];
910 }
911};
912
913
danno@chromium.org1044a4d2012-04-30 12:34:39 +0000914FunctionMirror.prototype.scopeCount = function() {
915 if (this.resolved()) {
916 return %GetFunctionScopeCount(this.value());
917 } else {
918 return 0;
919 }
920};
921
922
923FunctionMirror.prototype.scope = function(index) {
924 if (this.resolved()) {
925 return new ScopeMirror(void 0, this, index);
926 }
927};
928
929
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000930FunctionMirror.prototype.toText = function() {
931 return this.source();
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000932};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000933
934
935/**
936 * Mirror object for unresolved functions.
937 * @param {string} value The name for the unresolved function reflected by this
938 * mirror.
939 * @constructor
940 * @extends ObjectMirror
941 */
942function UnresolvedFunctionMirror(value) {
943 // Construct this using the ValueMirror as an unresolved function is not a
944 // real object but just a string.
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000945 %_CallFunction(this, FUNCTION_TYPE, value, ValueMirror);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000946 this.propertyCount_ = 0;
947 this.elementCount_ = 0;
948 this.resolved_ = false;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000949}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000950inherits(UnresolvedFunctionMirror, FunctionMirror);
951
952
953UnresolvedFunctionMirror.prototype.className = function() {
954 return 'Function';
955};
956
957
958UnresolvedFunctionMirror.prototype.constructorFunction = function() {
ager@chromium.org32912102009-01-16 10:38:43 +0000959 return GetUndefinedMirror();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000960};
961
962
963UnresolvedFunctionMirror.prototype.prototypeObject = function() {
ager@chromium.org32912102009-01-16 10:38:43 +0000964 return GetUndefinedMirror();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000965};
966
967
968UnresolvedFunctionMirror.prototype.protoObject = function() {
ager@chromium.org32912102009-01-16 10:38:43 +0000969 return GetUndefinedMirror();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970};
971
972
973UnresolvedFunctionMirror.prototype.name = function() {
974 return this.value_;
975};
976
977
ager@chromium.org9085a012009-05-11 19:22:57 +0000978UnresolvedFunctionMirror.prototype.inferredName = function() {
979 return undefined;
980};
981
982
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000983UnresolvedFunctionMirror.prototype.propertyNames = function(kind, limit) {
984 return [];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000985};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986
987
988/**
989 * Mirror object for arrays.
990 * @param {Array} value The Array object reflected by this mirror
991 * @constructor
992 * @extends ObjectMirror
993 */
994function ArrayMirror(value) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +0000995 %_CallFunction(this, value, ObjectMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000996}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000997inherits(ArrayMirror, ObjectMirror);
998
999
1000ArrayMirror.prototype.length = function() {
1001 return this.value_.length;
1002};
1003
1004
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001005ArrayMirror.prototype.indexedPropertiesFromRange = function(opt_from_index,
1006 opt_to_index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001007 var from_index = opt_from_index || 0;
1008 var to_index = opt_to_index || this.length() - 1;
1009 if (from_index > to_index) return new Array();
1010 var values = new Array(to_index - from_index + 1);
1011 for (var i = from_index; i <= to_index; i++) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001012 var details = %DebugGetPropertyDetails(this.value_, %ToString(i));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001013 var value;
1014 if (details) {
ager@chromium.org32912102009-01-16 10:38:43 +00001015 value = new PropertyMirror(this, i, details);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001016 } else {
ager@chromium.org32912102009-01-16 10:38:43 +00001017 value = GetUndefinedMirror();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001018 }
1019 values[i - from_index] = value;
1020 }
1021 return values;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001022};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001023
1024
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001025/**
1026 * Mirror object for dates.
1027 * @param {Date} value The Date object reflected by this mirror
1028 * @constructor
1029 * @extends ObjectMirror
1030 */
1031function DateMirror(value) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +00001032 %_CallFunction(this, value, ObjectMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001033}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001034inherits(DateMirror, ObjectMirror);
1035
1036
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037DateMirror.prototype.toText = function() {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00001038 var s = JSON.stringify(this.value_);
1039 return s.substring(1, s.length - 1); // cut quotes
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001040};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001041
1042
1043/**
1044 * Mirror object for regular expressions.
1045 * @param {RegExp} value The RegExp object reflected by this mirror
1046 * @constructor
1047 * @extends ObjectMirror
1048 */
1049function RegExpMirror(value) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +00001050 %_CallFunction(this, value, REGEXP_TYPE, ObjectMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001051}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001052inherits(RegExpMirror, ObjectMirror);
1053
1054
1055/**
1056 * Returns the source to the regular expression.
1057 * @return {string or undefined} The source to the regular expression
1058 */
1059RegExpMirror.prototype.source = function() {
1060 return this.value_.source;
1061};
1062
1063
1064/**
1065 * Returns whether this regular expression has the global (g) flag set.
1066 * @return {boolean} Value of the global flag
1067 */
1068RegExpMirror.prototype.global = function() {
1069 return this.value_.global;
1070};
1071
1072
1073/**
1074 * Returns whether this regular expression has the ignore case (i) flag set.
1075 * @return {boolean} Value of the ignore case flag
1076 */
1077RegExpMirror.prototype.ignoreCase = function() {
1078 return this.value_.ignoreCase;
1079};
1080
1081
1082/**
1083 * Returns whether this regular expression has the multiline (m) flag set.
1084 * @return {boolean} Value of the multiline flag
1085 */
1086RegExpMirror.prototype.multiline = function() {
1087 return this.value_.multiline;
1088};
1089
1090
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001091RegExpMirror.prototype.toText = function() {
1092 // Simpel to text which is used when on specialization in subclass.
1093 return "/" + this.source() + "/";
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001094};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001095
1096
1097/**
1098 * Mirror object for error objects.
1099 * @param {Error} value The error object reflected by this mirror
1100 * @constructor
1101 * @extends ObjectMirror
1102 */
1103function ErrorMirror(value) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +00001104 %_CallFunction(this, value, ERROR_TYPE, ObjectMirror);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001105}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001106inherits(ErrorMirror, ObjectMirror);
1107
1108
1109/**
1110 * Returns the message for this eror object.
1111 * @return {string or undefined} The message for this eror object
1112 */
1113ErrorMirror.prototype.message = function() {
1114 return this.value_.message;
1115};
1116
1117
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001118ErrorMirror.prototype.toText = function() {
1119 // Use the same text representation as in messages.js.
1120 var text;
1121 try {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001122 str = %_CallFunction(this.value_, builtins.ErrorToString);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001123 } catch (e) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001124 str = '#<Error>';
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001125 }
1126 return str;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001127};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001128
1129
1130/**
1131 * Base mirror object for properties.
1132 * @param {ObjectMirror} mirror The mirror object having this property
1133 * @param {string} name The name of the property
ager@chromium.org32912102009-01-16 10:38:43 +00001134 * @param {Array} details Details about the property
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001135 * @constructor
1136 * @extends Mirror
1137 */
ager@chromium.org32912102009-01-16 10:38:43 +00001138function PropertyMirror(mirror, name, details) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +00001139 %_CallFunction(this, PROPERTY_TYPE, Mirror);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001140 this.mirror_ = mirror;
1141 this.name_ = name;
ager@chromium.org32912102009-01-16 10:38:43 +00001142 this.value_ = details[0];
1143 this.details_ = details[1];
1144 if (details.length > 2) {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001145 this.exception_ = details[2];
ager@chromium.org32912102009-01-16 10:38:43 +00001146 this.getter_ = details[3];
1147 this.setter_ = details[4];
1148 }
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001149}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001150inherits(PropertyMirror, Mirror);
1151
1152
1153PropertyMirror.prototype.isReadOnly = function() {
1154 return (this.attributes() & PropertyAttribute.ReadOnly) != 0;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001155};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001156
1157
1158PropertyMirror.prototype.isEnum = function() {
1159 return (this.attributes() & PropertyAttribute.DontEnum) == 0;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001160};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001161
1162
1163PropertyMirror.prototype.canDelete = function() {
1164 return (this.attributes() & PropertyAttribute.DontDelete) == 0;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001165};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001166
1167
1168PropertyMirror.prototype.name = function() {
1169 return this.name_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001170};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001171
1172
1173PropertyMirror.prototype.isIndexed = function() {
1174 for (var i = 0; i < this.name_.length; i++) {
1175 if (this.name_[i] < '0' || '9' < this.name_[i]) {
1176 return false;
1177 }
1178 }
1179 return true;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001180};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001181
1182
1183PropertyMirror.prototype.value = function() {
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001184 return MakeMirror(this.value_, false);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001185};
ager@chromium.org32912102009-01-16 10:38:43 +00001186
1187
1188/**
1189 * Returns whether this property value is an exception.
1190 * @return {booolean} True if this property value is an exception
1191 */
1192PropertyMirror.prototype.isException = function() {
1193 return this.exception_ ? true : false;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001194};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001195
1196
1197PropertyMirror.prototype.attributes = function() {
1198 return %DebugPropertyAttributesFromDetails(this.details_);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001199};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001200
1201
1202PropertyMirror.prototype.propertyType = function() {
1203 return %DebugPropertyTypeFromDetails(this.details_);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001204};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001205
1206
1207PropertyMirror.prototype.insertionIndex = function() {
1208 return %DebugPropertyIndexFromDetails(this.details_);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001209};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001210
1211
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001212/**
ager@chromium.org32912102009-01-16 10:38:43 +00001213 * Returns whether this property has a getter defined through __defineGetter__.
1214 * @return {booolean} True if this property has a getter
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001215 */
ager@chromium.org32912102009-01-16 10:38:43 +00001216PropertyMirror.prototype.hasGetter = function() {
1217 return this.getter_ ? true : false;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001218};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001219
1220
1221/**
ager@chromium.org32912102009-01-16 10:38:43 +00001222 * Returns whether this property has a setter defined through __defineSetter__.
1223 * @return {booolean} True if this property has a setter
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001224 */
ager@chromium.org32912102009-01-16 10:38:43 +00001225PropertyMirror.prototype.hasSetter = function() {
1226 return this.setter_ ? true : false;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001227};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001228
1229
1230/**
ager@chromium.org32912102009-01-16 10:38:43 +00001231 * Returns the getter for this property defined through __defineGetter__.
1232 * @return {Mirror} FunctionMirror reflecting the getter function or
1233 * UndefinedMirror if there is no getter for this property
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001234 */
ager@chromium.org32912102009-01-16 10:38:43 +00001235PropertyMirror.prototype.getter = function() {
1236 if (this.hasGetter()) {
1237 return MakeMirror(this.getter_);
1238 } else {
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001239 return GetUndefinedMirror();
ager@chromium.org32912102009-01-16 10:38:43 +00001240 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001241};
ager@chromium.org32912102009-01-16 10:38:43 +00001242
1243
1244/**
1245 * Returns the setter for this property defined through __defineSetter__.
1246 * @return {Mirror} FunctionMirror reflecting the setter function or
1247 * UndefinedMirror if there is no setter for this property
1248 */
1249PropertyMirror.prototype.setter = function() {
1250 if (this.hasSetter()) {
1251 return MakeMirror(this.setter_);
1252 } else {
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001253 return GetUndefinedMirror();
ager@chromium.org32912102009-01-16 10:38:43 +00001254 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001255};
ager@chromium.org32912102009-01-16 10:38:43 +00001256
1257
1258/**
1259 * Returns whether this property is natively implemented by the host or a set
1260 * through JavaScript code.
lrn@chromium.org25156de2010-04-06 13:10:27 +00001261 * @return {boolean} True if the property is
ager@chromium.org32912102009-01-16 10:38:43 +00001262 * UndefinedMirror if there is no setter for this property
1263 */
1264PropertyMirror.prototype.isNative = function() {
1265 return (this.propertyType() == PropertyType.Interceptor) ||
1266 ((this.propertyType() == PropertyType.Callbacks) &&
1267 !this.hasGetter() && !this.hasSetter());
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001268};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001269
1270
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00001271var kFrameDetailsFrameIdIndex = 0;
1272var kFrameDetailsReceiverIndex = 1;
1273var kFrameDetailsFunctionIndex = 2;
1274var kFrameDetailsArgumentCountIndex = 3;
1275var kFrameDetailsLocalCountIndex = 4;
1276var kFrameDetailsSourcePositionIndex = 5;
1277var kFrameDetailsConstructCallIndex = 6;
1278var kFrameDetailsAtReturnIndex = 7;
1279var kFrameDetailsFlagsIndex = 8;
1280var kFrameDetailsFirstDynamicIndex = 9;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001281
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00001282var kFrameDetailsNameIndex = 0;
1283var kFrameDetailsValueIndex = 1;
1284var kFrameDetailsNameValueSize = 2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001285
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00001286var kFrameDetailsFlagDebuggerFrameMask = 1 << 0;
1287var kFrameDetailsFlagOptimizedFrameMask = 1 << 1;
1288var kFrameDetailsFlagInlinedFrameIndexMask = 7 << 2;
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001289
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001290/**
1291 * Wrapper for the frame details information retreived from the VM. The frame
1292 * details from the VM is an array with the following content. See runtime.cc
1293 * Runtime_GetFrameDetails.
1294 * 0: Id
1295 * 1: Receiver
1296 * 2: Function
1297 * 3: Argument count
1298 * 4: Local count
1299 * 5: Source position
1300 * 6: Construct call
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001301 * 7: Is at return
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001302 * 8: Flags (debugger frame, optimized frame, inlined frame index)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001303 * Arguments name, value
1304 * Locals name, value
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001305 * Return value if any
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001306 * @param {number} break_id Current break id
1307 * @param {number} index Frame number
1308 * @constructor
1309 */
1310function FrameDetails(break_id, index) {
1311 this.break_id_ = break_id;
1312 this.details_ = %GetFrameDetails(break_id, index);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001313}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001314
1315
1316FrameDetails.prototype.frameId = function() {
1317 %CheckExecutionState(this.break_id_);
1318 return this.details_[kFrameDetailsFrameIdIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001319};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001320
1321
1322FrameDetails.prototype.receiver = function() {
1323 %CheckExecutionState(this.break_id_);
1324 return this.details_[kFrameDetailsReceiverIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001325};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001326
1327
1328FrameDetails.prototype.func = function() {
1329 %CheckExecutionState(this.break_id_);
1330 return this.details_[kFrameDetailsFunctionIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001331};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001332
1333
1334FrameDetails.prototype.isConstructCall = function() {
1335 %CheckExecutionState(this.break_id_);
1336 return this.details_[kFrameDetailsConstructCallIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001337};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001338
1339
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001340FrameDetails.prototype.isAtReturn = function() {
1341 %CheckExecutionState(this.break_id_);
1342 return this.details_[kFrameDetailsAtReturnIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001343};
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001344
1345
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001346FrameDetails.prototype.isDebuggerFrame = function() {
1347 %CheckExecutionState(this.break_id_);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001348 var f = kFrameDetailsFlagDebuggerFrameMask;
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001349 return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001350};
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001351
1352
1353FrameDetails.prototype.isOptimizedFrame = function() {
1354 %CheckExecutionState(this.break_id_);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001355 var f = kFrameDetailsFlagOptimizedFrameMask;
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001356 return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001357};
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001358
1359
1360FrameDetails.prototype.isInlinedFrame = function() {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001361 return this.inlinedFrameIndex() > 0;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001362};
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001363
1364
1365FrameDetails.prototype.inlinedFrameIndex = function() {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001366 %CheckExecutionState(this.break_id_);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001367 var f = kFrameDetailsFlagInlinedFrameIndexMask;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001368 return (this.details_[kFrameDetailsFlagsIndex] & f) >> 2;
1369};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001370
1371
1372FrameDetails.prototype.argumentCount = function() {
1373 %CheckExecutionState(this.break_id_);
1374 return this.details_[kFrameDetailsArgumentCountIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001375};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001376
1377
1378FrameDetails.prototype.argumentName = function(index) {
1379 %CheckExecutionState(this.break_id_);
1380 if (index >= 0 && index < this.argumentCount()) {
1381 return this.details_[kFrameDetailsFirstDynamicIndex +
1382 index * kFrameDetailsNameValueSize +
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001383 kFrameDetailsNameIndex];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001385};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001386
1387
1388FrameDetails.prototype.argumentValue = function(index) {
1389 %CheckExecutionState(this.break_id_);
1390 if (index >= 0 && index < this.argumentCount()) {
1391 return this.details_[kFrameDetailsFirstDynamicIndex +
1392 index * kFrameDetailsNameValueSize +
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001393 kFrameDetailsValueIndex];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001394 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001395};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001396
1397
1398FrameDetails.prototype.localCount = function() {
1399 %CheckExecutionState(this.break_id_);
1400 return this.details_[kFrameDetailsLocalCountIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001401};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001402
1403
1404FrameDetails.prototype.sourcePosition = function() {
1405 %CheckExecutionState(this.break_id_);
1406 return this.details_[kFrameDetailsSourcePositionIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001407};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001408
1409
1410FrameDetails.prototype.localName = function(index) {
1411 %CheckExecutionState(this.break_id_);
1412 if (index >= 0 && index < this.localCount()) {
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001413 var locals_offset = kFrameDetailsFirstDynamicIndex +
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001414 this.argumentCount() * kFrameDetailsNameValueSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001415 return this.details_[locals_offset +
1416 index * kFrameDetailsNameValueSize +
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001417 kFrameDetailsNameIndex];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001418 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001419};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001420
1421
1422FrameDetails.prototype.localValue = function(index) {
1423 %CheckExecutionState(this.break_id_);
1424 if (index >= 0 && index < this.localCount()) {
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001425 var locals_offset = kFrameDetailsFirstDynamicIndex +
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001426 this.argumentCount() * kFrameDetailsNameValueSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001427 return this.details_[locals_offset +
1428 index * kFrameDetailsNameValueSize +
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001429 kFrameDetailsValueIndex];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001431};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001432
1433
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001434FrameDetails.prototype.returnValue = function() {
1435 %CheckExecutionState(this.break_id_);
1436 var return_value_offset =
1437 kFrameDetailsFirstDynamicIndex +
1438 (this.argumentCount() + this.localCount()) * kFrameDetailsNameValueSize;
1439 if (this.details_[kFrameDetailsAtReturnIndex]) {
1440 return this.details_[return_value_offset];
1441 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001442};
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001443
1444
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001445FrameDetails.prototype.scopeCount = function() {
1446 return %GetScopeCount(this.break_id_, this.frameId());
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001447};
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001448
1449
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001450/**
1451 * Mirror object for stack frames.
1452 * @param {number} break_id The break id in the VM for which this frame is
1453 valid
1454 * @param {number} index The frame index (top frame is index 0)
1455 * @constructor
1456 * @extends Mirror
1457 */
1458function FrameMirror(break_id, index) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +00001459 %_CallFunction(this, FRAME_TYPE, Mirror);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001460 this.break_id_ = break_id;
1461 this.index_ = index;
1462 this.details_ = new FrameDetails(break_id, index);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001463}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464inherits(FrameMirror, Mirror);
1465
1466
1467FrameMirror.prototype.index = function() {
1468 return this.index_;
1469};
1470
1471
1472FrameMirror.prototype.func = function() {
1473 // Get the function for this frame from the VM.
1474 var f = this.details_.func();
lrn@chromium.org25156de2010-04-06 13:10:27 +00001475
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001476 // Create a function mirror. NOTE: MakeMirror cannot be used here as the
1477 // value returned from the VM might be a string if the function for the
1478 // frame is unresolved.
1479 if (IS_FUNCTION(f)) {
ager@chromium.org32912102009-01-16 10:38:43 +00001480 return MakeMirror(f);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001481 } else {
1482 return new UnresolvedFunctionMirror(f);
1483 }
1484};
1485
1486
1487FrameMirror.prototype.receiver = function() {
1488 return MakeMirror(this.details_.receiver());
1489};
1490
1491
1492FrameMirror.prototype.isConstructCall = function() {
1493 return this.details_.isConstructCall();
1494};
1495
1496
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001497FrameMirror.prototype.isAtReturn = function() {
1498 return this.details_.isAtReturn();
1499};
1500
1501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001502FrameMirror.prototype.isDebuggerFrame = function() {
1503 return this.details_.isDebuggerFrame();
1504};
1505
1506
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001507FrameMirror.prototype.isOptimizedFrame = function() {
1508 return this.details_.isOptimizedFrame();
1509};
1510
1511
1512FrameMirror.prototype.isInlinedFrame = function() {
1513 return this.details_.isInlinedFrame();
1514};
1515
1516
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001517FrameMirror.prototype.inlinedFrameIndex = function() {
1518 return this.details_.inlinedFrameIndex();
1519};
1520
1521
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001522FrameMirror.prototype.argumentCount = function() {
1523 return this.details_.argumentCount();
1524};
1525
1526
1527FrameMirror.prototype.argumentName = function(index) {
1528 return this.details_.argumentName(index);
1529};
1530
1531
1532FrameMirror.prototype.argumentValue = function(index) {
1533 return MakeMirror(this.details_.argumentValue(index));
1534};
1535
1536
1537FrameMirror.prototype.localCount = function() {
1538 return this.details_.localCount();
1539};
1540
1541
1542FrameMirror.prototype.localName = function(index) {
1543 return this.details_.localName(index);
1544};
1545
1546
1547FrameMirror.prototype.localValue = function(index) {
1548 return MakeMirror(this.details_.localValue(index));
1549};
1550
1551
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001552FrameMirror.prototype.returnValue = function() {
1553 return MakeMirror(this.details_.returnValue());
1554};
1555
1556
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001557FrameMirror.prototype.sourcePosition = function() {
1558 return this.details_.sourcePosition();
1559};
1560
1561
1562FrameMirror.prototype.sourceLocation = function() {
1563 if (this.func().resolved() && this.func().script()) {
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001564 return this.func().script().locationFromPosition(this.sourcePosition(),
1565 true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001566 }
1567};
1568
1569
1570FrameMirror.prototype.sourceLine = function() {
1571 if (this.func().resolved()) {
1572 var location = this.sourceLocation();
1573 if (location) {
1574 return location.line;
1575 }
1576 }
1577};
1578
1579
1580FrameMirror.prototype.sourceColumn = function() {
1581 if (this.func().resolved()) {
1582 var location = this.sourceLocation();
1583 if (location) {
1584 return location.column;
1585 }
1586 }
1587};
1588
1589
1590FrameMirror.prototype.sourceLineText = function() {
1591 if (this.func().resolved()) {
1592 var location = this.sourceLocation();
1593 if (location) {
1594 return location.sourceText();
1595 }
1596 }
1597};
1598
1599
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001600FrameMirror.prototype.scopeCount = function() {
1601 return this.details_.scopeCount();
1602};
1603
1604
1605FrameMirror.prototype.scope = function(index) {
danno@chromium.org1044a4d2012-04-30 12:34:39 +00001606 return new ScopeMirror(this, void 0, index);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001607};
1608
1609
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001610FrameMirror.prototype.evaluate = function(source, disable_break,
1611 opt_context_object) {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001612 var result = %DebugEvaluate(this.break_id_,
1613 this.details_.frameId(),
1614 this.details_.inlinedFrameIndex(),
1615 source,
1616 Boolean(disable_break),
1617 opt_context_object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001618 return MakeMirror(result);
1619};
1620
1621
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622FrameMirror.prototype.invocationText = function() {
1623 // Format frame invoaction (receiver, function and arguments).
1624 var result = '';
1625 var func = this.func();
1626 var receiver = this.receiver();
1627 if (this.isConstructCall()) {
1628 // For constructor frames display new followed by the function name.
1629 result += 'new ';
1630 result += func.name() ? func.name() : '[anonymous]';
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001631 } else if (this.isDebuggerFrame()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632 result += '[debugger]';
1633 } else {
1634 // If the receiver has a className which is 'global' don't display it.
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001635 var display_receiver =
1636 !receiver.className || (receiver.className() != 'global');
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637 if (display_receiver) {
1638 result += receiver.toText();
1639 }
1640 // Try to find the function as a property in the receiver. Include the
1641 // prototype chain in the lookup.
ager@chromium.org32912102009-01-16 10:38:43 +00001642 var property = GetUndefinedMirror();
rossberg@chromium.org717967f2011-07-20 13:44:42 +00001643 if (receiver.isObject()) {
1644 for (var r = receiver;
1645 !r.isNull() && property.isUndefined();
1646 r = r.protoObject()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001647 property = r.lookupProperty(func);
1648 }
1649 }
1650 if (!property.isUndefined()) {
1651 // The function invoked was found on the receiver. Use the property name
1652 // for the backtrace.
1653 if (!property.isIndexed()) {
1654 if (display_receiver) {
1655 result += '.';
1656 }
1657 result += property.name();
1658 } else {
1659 result += '[';
1660 result += property.name();
1661 result += ']';
1662 }
1663 // Also known as - if the name in the function doesn't match the name
1664 // under which it was looked up.
1665 if (func.name() && func.name() != property.name()) {
1666 result += '(aka ' + func.name() + ')';
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001667 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001668 } else {
1669 // The function invoked was not found on the receiver. Use the function
1670 // name if available for the backtrace.
1671 if (display_receiver) {
1672 result += '.';
1673 }
1674 result += func.name() ? func.name() : '[anonymous]';
1675 }
1676 }
1677
1678 // Render arguments for normal frames.
1679 if (!this.isDebuggerFrame()) {
1680 result += '(';
1681 for (var i = 0; i < this.argumentCount(); i++) {
1682 if (i != 0) result += ', ';
1683 if (this.argumentName(i)) {
1684 result += this.argumentName(i);
1685 result += '=';
1686 }
1687 result += this.argumentValue(i).toText();
1688 }
1689 result += ')';
1690 }
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001691
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00001692 if (this.isAtReturn()) {
1693 result += ' returning ';
1694 result += this.returnValue().toText();
1695 }
vegorov@chromium.org42841962010-10-18 11:18:59 +00001696
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001697 return result;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001698};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001699
1700
1701FrameMirror.prototype.sourceAndPositionText = function() {
1702 // Format source and position.
1703 var result = '';
1704 var func = this.func();
1705 if (func.resolved()) {
1706 if (func.script()) {
1707 if (func.script().name()) {
1708 result += func.script().name();
1709 } else {
1710 result += '[unnamed]';
1711 }
1712 if (!this.isDebuggerFrame()) {
1713 var location = this.sourceLocation();
1714 result += ' line ';
1715 result += !IS_UNDEFINED(location) ? (location.line + 1) : '?';
1716 result += ' column ';
1717 result += !IS_UNDEFINED(location) ? (location.column + 1) : '?';
1718 if (!IS_UNDEFINED(this.sourcePosition())) {
1719 result += ' (position ' + (this.sourcePosition() + 1) + ')';
1720 }
1721 }
1722 } else {
1723 result += '[no source]';
1724 }
1725 } else {
1726 result += '[unresolved]';
1727 }
1728
1729 return result;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001730};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001731
1732
1733FrameMirror.prototype.localsText = function() {
1734 // Format local variables.
1735 var result = '';
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001736 var locals_count = this.localCount();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001737 if (locals_count > 0) {
1738 for (var i = 0; i < locals_count; ++i) {
1739 result += ' var ';
1740 result += this.localName(i);
1741 result += ' = ';
1742 result += this.localValue(i).toText();
1743 if (i < locals_count - 1) result += '\n';
1744 }
1745 }
1746
1747 return result;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001748};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749
1750
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001751FrameMirror.prototype.restart = function() {
1752 var result = %LiveEditRestartFrame(this.break_id_, this.index_);
1753 if (IS_UNDEFINED(result)) {
1754 result = "Failed to find requested frame";
1755 }
1756 return result;
1757};
1758
1759
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760FrameMirror.prototype.toText = function(opt_locals) {
1761 var result = '';
1762 result += '#' + (this.index() <= 9 ? '0' : '') + this.index();
1763 result += ' ';
1764 result += this.invocationText();
1765 result += ' ';
1766 result += this.sourceAndPositionText();
1767 if (opt_locals) {
1768 result += '\n';
1769 result += this.localsText();
1770 }
1771 return result;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001772};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001773
1774
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00001775var kScopeDetailsTypeIndex = 0;
1776var kScopeDetailsObjectIndex = 1;
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001777
danno@chromium.org1044a4d2012-04-30 12:34:39 +00001778function ScopeDetails(frame, fun, index) {
1779 if (frame) {
1780 this.break_id_ = frame.break_id_;
1781 this.details_ = %GetScopeDetails(frame.break_id_,
1782 frame.details_.frameId(),
1783 frame.details_.inlinedFrameIndex(),
1784 index);
1785 } else {
1786 this.details_ = %GetFunctionScopeDetails(fun.value(), index);
1787 this.break_id_ = undefined;
1788 }
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001789}
1790
1791
1792ScopeDetails.prototype.type = function() {
danno@chromium.org1044a4d2012-04-30 12:34:39 +00001793 if (!IS_UNDEFINED(this.break_id_)) {
1794 %CheckExecutionState(this.break_id_);
1795 }
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001796 return this.details_[kScopeDetailsTypeIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001797};
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001798
1799
1800ScopeDetails.prototype.object = function() {
danno@chromium.org1044a4d2012-04-30 12:34:39 +00001801 if (!IS_UNDEFINED(this.break_id_)) {
1802 %CheckExecutionState(this.break_id_);
1803 }
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001804 return this.details_[kScopeDetailsObjectIndex];
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001805};
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001806
1807
1808/**
danno@chromium.org1044a4d2012-04-30 12:34:39 +00001809 * Mirror object for scope of frame or function. Either frame or function must
1810 * be specified.
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001811 * @param {FrameMirror} frame The frame this scope is a part of
danno@chromium.org1044a4d2012-04-30 12:34:39 +00001812 * @param {FunctionMirror} function The function this scope is a part of
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001813 * @param {number} index The scope index in the frame
1814 * @constructor
1815 * @extends Mirror
1816 */
danno@chromium.org1044a4d2012-04-30 12:34:39 +00001817function ScopeMirror(frame, function, index) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +00001818 %_CallFunction(this, SCOPE_TYPE, Mirror);
danno@chromium.org1044a4d2012-04-30 12:34:39 +00001819 if (frame) {
1820 this.frame_index_ = frame.index_;
1821 } else {
1822 this.frame_index_ = undefined;
1823 }
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001824 this.scope_index_ = index;
danno@chromium.org1044a4d2012-04-30 12:34:39 +00001825 this.details_ = new ScopeDetails(frame, function, index);
ager@chromium.orgeadaf222009-06-16 09:43:10 +00001826}
1827inherits(ScopeMirror, Mirror);
1828
1829
1830ScopeMirror.prototype.frameIndex = function() {
1831 return this.frame_index_;
1832};
1833
1834
1835ScopeMirror.prototype.scopeIndex = function() {
1836 return this.scope_index_;
1837};
1838
1839
1840ScopeMirror.prototype.scopeType = function() {
1841 return this.details_.type();
1842};
1843
1844
1845ScopeMirror.prototype.scopeObject = function() {
1846 // For local and closure scopes create a transient mirror as these objects are
1847 // created on the fly materializing the local or closure scopes and
1848 // therefore will not preserve identity.
1849 var transient = this.scopeType() == ScopeType.Local ||
1850 this.scopeType() == ScopeType.Closure;
1851 return MakeMirror(this.details_.object(), transient);
1852};
1853
1854
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001855/**
1856 * Mirror object for script source.
1857 * @param {Script} script The script object
1858 * @constructor
1859 * @extends Mirror
1860 */
1861function ScriptMirror(script) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +00001862 %_CallFunction(this, SCRIPT_TYPE, Mirror);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001863 this.script_ = script;
ager@chromium.org9085a012009-05-11 19:22:57 +00001864 this.context_ = new ContextMirror(script.context_data);
ager@chromium.orgddb913d2009-01-27 10:01:48 +00001865 this.allocateHandle_();
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00001866}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001867inherits(ScriptMirror, Mirror);
1868
1869
iposva@chromium.org245aa852009-02-10 00:49:54 +00001870ScriptMirror.prototype.value = function() {
1871 return this.script_;
1872};
1873
1874
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001875ScriptMirror.prototype.name = function() {
lrn@chromium.org25156de2010-04-06 13:10:27 +00001876 return this.script_.name || this.script_.nameOrSourceURL();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877};
1878
1879
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00001880ScriptMirror.prototype.id = function() {
1881 return this.script_.id;
1882};
1883
1884
iposva@chromium.org245aa852009-02-10 00:49:54 +00001885ScriptMirror.prototype.source = function() {
1886 return this.script_.source;
1887};
1888
1889
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00001890ScriptMirror.prototype.setSource = function(source) {
1891 %DebugSetScriptSource(this.script_, source);
1892};
1893
1894
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001895ScriptMirror.prototype.lineOffset = function() {
1896 return this.script_.line_offset;
1897};
1898
1899
1900ScriptMirror.prototype.columnOffset = function() {
1901 return this.script_.column_offset;
1902};
1903
1904
ager@chromium.org65dad4b2009-04-23 08:48:43 +00001905ScriptMirror.prototype.data = function() {
1906 return this.script_.data;
1907};
1908
1909
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001910ScriptMirror.prototype.scriptType = function() {
1911 return this.script_.type;
1912};
1913
1914
ager@chromium.orge2902be2009-06-08 12:21:35 +00001915ScriptMirror.prototype.compilationType = function() {
1916 return this.script_.compilation_type;
1917};
1918
1919
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001920ScriptMirror.prototype.lineCount = function() {
1921 return this.script_.lineCount();
1922};
1923
1924
ager@chromium.org3a6061e2009-03-12 14:24:36 +00001925ScriptMirror.prototype.locationFromPosition = function(
1926 position, include_resource_offset) {
1927 return this.script_.locationFromPosition(position, include_resource_offset);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001928};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001929
1930
1931ScriptMirror.prototype.sourceSlice = function (opt_from_line, opt_to_line) {
1932 return this.script_.sourceSlice(opt_from_line, opt_to_line);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001933};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001934
1935
ager@chromium.org9085a012009-05-11 19:22:57 +00001936ScriptMirror.prototype.context = function() {
1937 return this.context_;
1938};
1939
1940
sgjesse@chromium.org98180592009-12-02 08:17:28 +00001941ScriptMirror.prototype.evalFromScript = function() {
1942 return MakeMirror(this.script_.eval_from_script);
1943};
1944
1945
1946ScriptMirror.prototype.evalFromFunctionName = function() {
1947 return MakeMirror(this.script_.eval_from_function_name);
ager@chromium.orge2902be2009-06-08 12:21:35 +00001948};
1949
1950
1951ScriptMirror.prototype.evalFromLocation = function() {
sgjesse@chromium.org98180592009-12-02 08:17:28 +00001952 var eval_from_script = this.evalFromScript();
1953 if (!eval_from_script.isUndefined()) {
1954 var position = this.script_.eval_from_script_position;
1955 return eval_from_script.locationFromPosition(position, true);
ager@chromium.orge2902be2009-06-08 12:21:35 +00001956 }
1957};
1958
1959
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001960ScriptMirror.prototype.toText = function() {
1961 var result = '';
1962 result += this.name();
1963 result += ' (lines: ';
1964 if (this.lineOffset() > 0) {
1965 result += this.lineOffset();
1966 result += '-';
1967 result += this.lineOffset() + this.lineCount() - 1;
1968 } else {
1969 result += this.lineCount();
1970 }
1971 result += ')';
1972 return result;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001973};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001974
1975
ager@chromium.org32912102009-01-16 10:38:43 +00001976/**
ager@chromium.org9085a012009-05-11 19:22:57 +00001977 * Mirror object for context.
1978 * @param {Object} data The context data
1979 * @constructor
1980 * @extends Mirror
1981 */
1982function ContextMirror(data) {
whesse@chromium.org7a392b32011-01-31 11:30:36 +00001983 %_CallFunction(this, CONTEXT_TYPE, Mirror);
ager@chromium.org9085a012009-05-11 19:22:57 +00001984 this.data_ = data;
1985 this.allocateHandle_();
1986}
1987inherits(ContextMirror, Mirror);
1988
1989
1990ContextMirror.prototype.data = function() {
1991 return this.data_;
1992};
1993
1994
1995/**
ager@chromium.org32912102009-01-16 10:38:43 +00001996 * Returns a mirror serializer
1997 *
1998 * @param {boolean} details Set to true to include details
ager@chromium.org9085a012009-05-11 19:22:57 +00001999 * @param {Object} options Options comtrolling the serialization
2000 * The following options can be set:
2001 * includeSource: include ths full source of scripts
ager@chromium.org32912102009-01-16 10:38:43 +00002002 * @returns {MirrorSerializer} mirror serializer
2003 */
ager@chromium.org9085a012009-05-11 19:22:57 +00002004function MakeMirrorSerializer(details, options) {
2005 return new JSONProtocolSerializer(details, options);
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002006}
2007
2008
ager@chromium.org32912102009-01-16 10:38:43 +00002009/**
2010 * Object for serializing a mirror objects and its direct references.
2011 * @param {boolean} details Indicates whether to include details for the mirror
2012 * serialized
2013 * @constructor
2014 */
ager@chromium.org9085a012009-05-11 19:22:57 +00002015function JSONProtocolSerializer(details, options) {
ager@chromium.org32912102009-01-16 10:38:43 +00002016 this.details_ = details;
ager@chromium.org9085a012009-05-11 19:22:57 +00002017 this.options_ = options;
ager@chromium.org32912102009-01-16 10:38:43 +00002018 this.mirrors_ = [ ];
2019}
2020
2021
2022/**
2023 * Returns a serialization of an object reference. The referenced object are
2024 * added to the serialization state.
2025 *
2026 * @param {Mirror} mirror The mirror to serialize
2027 * @returns {String} JSON serialization
2028 */
2029JSONProtocolSerializer.prototype.serializeReference = function(mirror) {
2030 return this.serialize_(mirror, true, true);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002031};
ager@chromium.org32912102009-01-16 10:38:43 +00002032
2033
2034/**
2035 * Returns a serialization of an object value. The referenced objects are
2036 * added to the serialization state.
2037 *
2038 * @param {Mirror} mirror The mirror to serialize
2039 * @returns {String} JSON serialization
2040 */
2041JSONProtocolSerializer.prototype.serializeValue = function(mirror) {
2042 var json = this.serialize_(mirror, false, true);
2043 return json;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002044};
ager@chromium.org32912102009-01-16 10:38:43 +00002045
2046
2047/**
2048 * Returns a serialization of all the objects referenced.
2049 *
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002050 * @param {Mirror} mirror The mirror to serialize.
2051 * @returns {Array.<Object>} Array of the referenced objects converted to
2052 * protcol objects.
ager@chromium.org32912102009-01-16 10:38:43 +00002053 */
2054JSONProtocolSerializer.prototype.serializeReferencedObjects = function() {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002055 // Collect the protocol representation of the referenced objects in an array.
2056 var content = [];
lrn@chromium.org25156de2010-04-06 13:10:27 +00002057
ager@chromium.org32912102009-01-16 10:38:43 +00002058 // Get the number of referenced objects.
2059 var count = this.mirrors_.length;
lrn@chromium.org25156de2010-04-06 13:10:27 +00002060
ager@chromium.org32912102009-01-16 10:38:43 +00002061 for (var i = 0; i < count; i++) {
2062 content.push(this.serialize_(this.mirrors_[i], false, false));
2063 }
2064
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002065 return content;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002066};
ager@chromium.org32912102009-01-16 10:38:43 +00002067
2068
ager@chromium.org9085a012009-05-11 19:22:57 +00002069JSONProtocolSerializer.prototype.includeSource_ = function() {
2070 return this.options_ && this.options_.includeSource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002071};
ager@chromium.org9085a012009-05-11 19:22:57 +00002072
2073
ager@chromium.org3e875802009-06-29 08:26:34 +00002074JSONProtocolSerializer.prototype.inlineRefs_ = function() {
2075 return this.options_ && this.options_.inlineRefs;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002076};
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002077
2078
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +00002079JSONProtocolSerializer.prototype.maxStringLength_ = function() {
2080 if (IS_UNDEFINED(this.options_) ||
2081 IS_UNDEFINED(this.options_.maxStringLength)) {
2082 return kMaxProtocolStringLength;
2083 }
2084 return this.options_.maxStringLength;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002085};
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +00002086
2087
ager@chromium.org32912102009-01-16 10:38:43 +00002088JSONProtocolSerializer.prototype.add_ = function(mirror) {
2089 // If this mirror is already in the list just return.
2090 for (var i = 0; i < this.mirrors_.length; i++) {
2091 if (this.mirrors_[i] === mirror) {
2092 return;
2093 }
2094 }
lrn@chromium.org25156de2010-04-06 13:10:27 +00002095
ager@chromium.org32912102009-01-16 10:38:43 +00002096 // Add the mirror to the list of mirrors to be serialized.
2097 this.mirrors_.push(mirror);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002098};
ager@chromium.org32912102009-01-16 10:38:43 +00002099
2100
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002101/**
2102 * Formats mirror object to protocol reference object with some data that can
2103 * be used to display the value in debugger.
2104 * @param {Mirror} mirror Mirror to serialize.
2105 * @return {Object} Protocol reference object.
2106 */
lrn@chromium.org25156de2010-04-06 13:10:27 +00002107JSONProtocolSerializer.prototype.serializeReferenceWithDisplayData_ =
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002108 function(mirror) {
2109 var o = {};
2110 o.ref = mirror.handle();
2111 o.type = mirror.type();
2112 switch (mirror.type()) {
2113 case UNDEFINED_TYPE:
2114 case NULL_TYPE:
2115 case BOOLEAN_TYPE:
2116 case NUMBER_TYPE:
2117 o.value = mirror.value();
2118 break;
2119 case STRING_TYPE:
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +00002120 o.value = mirror.getTruncatedValue(this.maxStringLength_());
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002121 break;
2122 case FUNCTION_TYPE:
2123 o.name = mirror.name();
2124 o.inferredName = mirror.inferredName();
2125 if (mirror.script()) {
2126 o.scriptId = mirror.script().id();
2127 }
2128 break;
2129 case ERROR_TYPE:
2130 case REGEXP_TYPE:
2131 o.value = mirror.toText();
2132 break;
2133 case OBJECT_TYPE:
2134 o.className = mirror.className();
2135 break;
2136 }
2137 return o;
2138};
2139
ager@chromium.orgeadaf222009-06-16 09:43:10 +00002140
ager@chromium.org32912102009-01-16 10:38:43 +00002141JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
2142 details) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +00002143 // If serializing a reference to a mirror just return the reference and add
2144 // the mirror to the referenced mirrors.
2145 if (reference &&
ager@chromium.org9085a012009-05-11 19:22:57 +00002146 (mirror.isValue() || mirror.isScript() || mirror.isContext())) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002147 if (this.inlineRefs_() && mirror.isValue()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002148 return this.serializeReferenceWithDisplayData_(mirror);
2149 } else {
2150 this.add_(mirror);
2151 return {'ref' : mirror.handle()};
2152 }
ager@chromium.org32912102009-01-16 10:38:43 +00002153 }
lrn@chromium.org25156de2010-04-06 13:10:27 +00002154
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002155 // Collect the JSON property/value pairs.
2156 var content = {};
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002157
kasperl@chromium.org2d18d102009-04-15 13:27:32 +00002158 // Add the mirror handle.
ager@chromium.org9085a012009-05-11 19:22:57 +00002159 if (mirror.isValue() || mirror.isScript() || mirror.isContext()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002160 content.handle = mirror.handle();
ager@chromium.org32912102009-01-16 10:38:43 +00002161 }
2162
2163 // Always add the type.
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002164 content.type = mirror.type();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002165
2166 switch (mirror.type()) {
2167 case UNDEFINED_TYPE:
2168 case NULL_TYPE:
2169 // Undefined and null are represented just by their type.
2170 break;
2171
2172 case BOOLEAN_TYPE:
2173 // Boolean values are simply represented by their value.
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002174 content.value = mirror.value();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002175 break;
2176
2177 case NUMBER_TYPE:
2178 // Number values are simply represented by their value.
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002179 content.value = NumberToJSON_(mirror.value());
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002180 break;
2181
2182 case STRING_TYPE:
2183 // String values might have their value cropped to keep down size.
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +00002184 if (this.maxStringLength_() != -1 &&
2185 mirror.length() > this.maxStringLength_()) {
2186 var str = mirror.getTruncatedValue(this.maxStringLength_());
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002187 content.value = str;
2188 content.fromIndex = 0;
fschneider@chromium.orgb95b98b2010-02-23 10:34:29 +00002189 content.toIndex = this.maxStringLength_();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002190 } else {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002191 content.value = mirror.value();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002192 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002193 content.length = mirror.length();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002194 break;
2195
2196 case OBJECT_TYPE:
2197 case FUNCTION_TYPE:
2198 case ERROR_TYPE:
2199 case REGEXP_TYPE:
2200 // Add object representation.
ager@chromium.org32912102009-01-16 10:38:43 +00002201 this.serializeObject_(mirror, content, details);
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002202 break;
2203
2204 case PROPERTY_TYPE:
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002205 throw new Error('PropertyMirror cannot be serialized independeltly');
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002206 break;
2207
2208 case FRAME_TYPE:
2209 // Add object representation.
2210 this.serializeFrame_(mirror, content);
2211 break;
2212
ager@chromium.orgeadaf222009-06-16 09:43:10 +00002213 case SCOPE_TYPE:
2214 // Add object representation.
2215 this.serializeScope_(mirror, content);
2216 break;
2217
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002218 case SCRIPT_TYPE:
kasperl@chromium.org2d18d102009-04-15 13:27:32 +00002219 // Script is represented by id, name and source attributes.
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002220 if (mirror.name()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002221 content.name = mirror.name();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002222 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002223 content.id = mirror.id();
2224 content.lineOffset = mirror.lineOffset();
2225 content.columnOffset = mirror.columnOffset();
2226 content.lineCount = mirror.lineCount();
ager@chromium.org9085a012009-05-11 19:22:57 +00002227 if (mirror.data()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002228 content.data = mirror.data();
ager@chromium.org9085a012009-05-11 19:22:57 +00002229 }
2230 if (this.includeSource_()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002231 content.source = mirror.source();
ager@chromium.org9085a012009-05-11 19:22:57 +00002232 } else {
2233 var sourceStart = mirror.source().substring(0, 80);
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002234 content.sourceStart = sourceStart;
ager@chromium.org9085a012009-05-11 19:22:57 +00002235 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002236 content.sourceLength = mirror.source().length;
2237 content.scriptType = mirror.scriptType();
ager@chromium.orge2902be2009-06-08 12:21:35 +00002238 content.compilationType = mirror.compilationType();
sgjesse@chromium.org636edf42009-06-18 14:43:07 +00002239 // For compilation type eval emit information on the script from which
2240 // eval was called if a script is present.
2241 if (mirror.compilationType() == 1 &&
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002242 mirror.evalFromScript()) {
ager@chromium.orge2902be2009-06-08 12:21:35 +00002243 content.evalFromScript =
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002244 this.serializeReference(mirror.evalFromScript());
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002245 var evalFromLocation = mirror.evalFromLocation();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002246 if (evalFromLocation) {
2247 content.evalFromLocation = { line: evalFromLocation.line,
2248 column: evalFromLocation.column };
2249 }
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002250 if (mirror.evalFromFunctionName()) {
2251 content.evalFromFunctionName = mirror.evalFromFunctionName();
2252 }
ager@chromium.orge2902be2009-06-08 12:21:35 +00002253 }
ager@chromium.org9085a012009-05-11 19:22:57 +00002254 if (mirror.context()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002255 content.context = this.serializeReference(mirror.context());
ager@chromium.org9085a012009-05-11 19:22:57 +00002256 }
2257 break;
2258
2259 case CONTEXT_TYPE:
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002260 content.data = mirror.data();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002261 break;
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002262 }
2263
2264 // Always add the text representation.
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002265 content.text = mirror.toText();
lrn@chromium.org25156de2010-04-06 13:10:27 +00002266
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002267 // Create and return the JSON string.
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002268 return content;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002269};
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002270
2271
ager@chromium.org32912102009-01-16 10:38:43 +00002272/**
2273 * Serialize object information to the following JSON format.
2274 *
2275 * {"className":"<class name>",
2276 * "constructorFunction":{"ref":<number>},
2277 * "protoObject":{"ref":<number>},
2278 * "prototypeObject":{"ref":<number>},
2279 * "namedInterceptor":<boolean>,
2280 * "indexedInterceptor":<boolean>,
2281 * "properties":[<properties>]}
2282 */
2283JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
2284 details) {
2285 // Add general object properties.
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002286 content.className = mirror.className();
2287 content.constructorFunction =
2288 this.serializeReference(mirror.constructorFunction());
2289 content.protoObject = this.serializeReference(mirror.protoObject());
2290 content.prototypeObject = this.serializeReference(mirror.prototypeObject());
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002291
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00002292 var primitiveValue = mirror.primitiveValue();
2293 if (!IS_UNDEFINED(primitiveValue)) {
2294 content.primitiveValue = this.serializeReference(primitiveValue);
2295 }
2296
ager@chromium.org32912102009-01-16 10:38:43 +00002297 // Add flags to indicate whether there are interceptors.
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002298 if (mirror.hasNamedInterceptor()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002299 content.namedInterceptor = true;
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002300 }
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002301 if (mirror.hasIndexedInterceptor()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002302 content.indexedInterceptor = true;
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002303 }
lrn@chromium.org25156de2010-04-06 13:10:27 +00002304
ager@chromium.org32912102009-01-16 10:38:43 +00002305 // Add function specific properties.
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002306 if (mirror.isFunction()) {
2307 // Add function specific properties.
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002308 content.name = mirror.name();
ager@chromium.org9085a012009-05-11 19:22:57 +00002309 if (!IS_UNDEFINED(mirror.inferredName())) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002310 content.inferredName = mirror.inferredName();
ager@chromium.org9085a012009-05-11 19:22:57 +00002311 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002312 content.resolved = mirror.resolved();
ager@chromium.org32912102009-01-16 10:38:43 +00002313 if (mirror.resolved()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002314 content.source = mirror.source();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002315 }
2316 if (mirror.script()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002317 content.script = this.serializeReference(mirror.script());
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002318 content.scriptId = mirror.script().id();
lrn@chromium.org25156de2010-04-06 13:10:27 +00002319
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002320 serializeLocationFields(mirror.sourceLocation(), content);
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002321 }
danno@chromium.org1044a4d2012-04-30 12:34:39 +00002322
2323 content.scopes = [];
2324 for (var i = 0; i < mirror.scopeCount(); i++) {
2325 var scope = mirror.scope(i);
2326 content.scopes.push({
2327 type: scope.scopeType(),
2328 index: i
2329 });
2330 }
ager@chromium.org32912102009-01-16 10:38:43 +00002331 }
2332
2333 // Add date specific properties.
2334 if (mirror.isDate()) {
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002335 // Add date specific properties.
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002336 content.value = mirror.value();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002337 }
ager@chromium.org32912102009-01-16 10:38:43 +00002338
2339 // Add actual properties - named properties followed by indexed properties.
2340 var propertyNames = mirror.propertyNames(PropertyKind.Named);
2341 var propertyIndexes = mirror.propertyNames(PropertyKind.Indexed);
2342 var p = new Array(propertyNames.length + propertyIndexes.length);
2343 for (var i = 0; i < propertyNames.length; i++) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002344 var propertyMirror = mirror.property(propertyNames[i]);
2345 p[i] = this.serializeProperty_(propertyMirror);
ager@chromium.org32912102009-01-16 10:38:43 +00002346 if (details) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002347 this.add_(propertyMirror.value());
ager@chromium.org32912102009-01-16 10:38:43 +00002348 }
2349 }
2350 for (var i = 0; i < propertyIndexes.length; i++) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002351 var propertyMirror = mirror.property(propertyIndexes[i]);
2352 p[propertyNames.length + i] = this.serializeProperty_(propertyMirror);
ager@chromium.org32912102009-01-16 10:38:43 +00002353 if (details) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002354 this.add_(propertyMirror.value());
ager@chromium.org32912102009-01-16 10:38:43 +00002355 }
2356 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002357 content.properties = p;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002358};
ager@chromium.org32912102009-01-16 10:38:43 +00002359
2360
2361/**
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002362 * Serialize location information to the following JSON format:
2363 *
2364 * "position":"<position>",
2365 * "line":"<line>",
2366 * "column":"<column>",
lrn@chromium.org25156de2010-04-06 13:10:27 +00002367 *
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002368 * @param {SourceLocation} location The location to serialize, may be undefined.
2369 */
2370function serializeLocationFields (location, content) {
2371 if (!location) {
2372 return;
lrn@chromium.org25156de2010-04-06 13:10:27 +00002373 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002374 content.position = location.position;
2375 var line = location.line;
2376 if (!IS_UNDEFINED(line)) {
2377 content.line = line;
2378 }
2379 var column = location.column;
2380 if (!IS_UNDEFINED(column)) {
2381 content.column = column;
2382 }
2383}
2384
2385
2386/**
ager@chromium.org32912102009-01-16 10:38:43 +00002387 * Serialize property information to the following JSON format for building the
2388 * array of properties.
2389 *
2390 * {"name":"<property name>",
2391 * "attributes":<number>,
2392 * "propertyType":<number>,
2393 * "ref":<number>}
2394 *
2395 * If the attribute for the property is PropertyAttribute.None it is not added.
2396 * If the propertyType for the property is PropertyType.Normal it is not added.
2397 * Here are a couple of examples.
2398 *
2399 * {"name":"hello","ref":1}
2400 * {"name":"length","attributes":7,"propertyType":3,"ref":2}
2401 *
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002402 * @param {PropertyMirror} propertyMirror The property to serialize.
2403 * @returns {Object} Protocol object representing the property.
ager@chromium.org32912102009-01-16 10:38:43 +00002404 */
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002405JSONProtocolSerializer.prototype.serializeProperty_ = function(propertyMirror) {
2406 var result = {};
lrn@chromium.org25156de2010-04-06 13:10:27 +00002407
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002408 result.name = propertyMirror.name();
2409 var propertyValue = propertyMirror.value();
ager@chromium.org3e875802009-06-29 08:26:34 +00002410 if (this.inlineRefs_() && propertyValue.isValue()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002411 result.value = this.serializeReferenceWithDisplayData_(propertyValue);
2412 } else {
2413 if (propertyMirror.attributes() != PropertyAttribute.None) {
2414 result.attributes = propertyMirror.attributes();
2415 }
2416 if (propertyMirror.propertyType() != PropertyType.Normal) {
2417 result.propertyType = propertyMirror.propertyType();
2418 }
2419 result.ref = propertyValue.handle();
ager@chromium.org32912102009-01-16 10:38:43 +00002420 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002421 return result;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002422};
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002423
2424
2425JSONProtocolSerializer.prototype.serializeFrame_ = function(mirror, content) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002426 content.index = mirror.index();
2427 content.receiver = this.serializeReference(mirror.receiver());
kasperl@chromium.org2d18d102009-04-15 13:27:32 +00002428 var func = mirror.func();
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002429 content.func = this.serializeReference(func);
kasperl@chromium.org2d18d102009-04-15 13:27:32 +00002430 if (func.script()) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002431 content.script = this.serializeReference(func.script());
kasperl@chromium.org2d18d102009-04-15 13:27:32 +00002432 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002433 content.constructCall = mirror.isConstructCall();
ager@chromium.org2cc82ae2010-06-14 07:35:38 +00002434 content.atReturn = mirror.isAtReturn();
2435 if (mirror.isAtReturn()) {
2436 content.returnValue = this.serializeReference(mirror.returnValue());
2437 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002438 content.debuggerFrame = mirror.isDebuggerFrame();
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002439 var x = new Array(mirror.argumentCount());
2440 for (var i = 0; i < mirror.argumentCount(); i++) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002441 var arg = {};
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002442 var argument_name = mirror.argumentName(i);
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002443 if (argument_name) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002444 arg.name = argument_name;
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002445 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002446 arg.value = this.serializeReference(mirror.argumentValue(i));
2447 x[i] = arg;
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002448 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002449 content.arguments = x;
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002450 var x = new Array(mirror.localCount());
2451 for (var i = 0; i < mirror.localCount(); i++) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002452 var local = {};
2453 local.name = mirror.localName(i);
2454 local.value = this.serializeReference(mirror.localValue(i));
2455 x[i] = local;
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002456 }
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002457 content.locals = x;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002458 serializeLocationFields(mirror.sourceLocation(), content);
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002459 var source_line_text = mirror.sourceLineText();
2460 if (!IS_UNDEFINED(source_line_text)) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002461 content.sourceLineText = source_line_text;
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002462 }
lrn@chromium.org25156de2010-04-06 13:10:27 +00002463
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002464 content.scopes = [];
2465 for (var i = 0; i < mirror.scopeCount(); i++) {
2466 var scope = mirror.scope(i);
2467 content.scopes.push({
2468 type: scope.scopeType(),
2469 index: i
2470 });
2471 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002472};
christian.plesner.hansen@gmail.comaca49682009-01-07 14:29:04 +00002473
2474
ager@chromium.orgeadaf222009-06-16 09:43:10 +00002475JSONProtocolSerializer.prototype.serializeScope_ = function(mirror, content) {
2476 content.index = mirror.scopeIndex();
2477 content.frameIndex = mirror.frameIndex();
2478 content.type = mirror.scopeType();
ager@chromium.org3e875802009-06-29 08:26:34 +00002479 content.object = this.inlineRefs_() ?
2480 this.serializeValue(mirror.scopeObject()) :
2481 this.serializeReference(mirror.scopeObject());
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002482};
ager@chromium.orgeadaf222009-06-16 09:43:10 +00002483
2484
sgjesse@chromium.org715915b2009-01-19 16:08:47 +00002485/**
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002486 * Convert a number to a protocol value. For all finite numbers the number
2487 * itself is returned. For non finite numbers NaN, Infinite and
sgjesse@chromium.org715915b2009-01-19 16:08:47 +00002488 * -Infinite the string representation "NaN", "Infinite" or "-Infinite"
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002489 * (not including the quotes) is returned.
sgjesse@chromium.org715915b2009-01-19 16:08:47 +00002490 *
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002491 * @param {number} value The number value to convert to a protocol value.
2492 * @returns {number|string} Protocol value.
sgjesse@chromium.org715915b2009-01-19 16:08:47 +00002493 */
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002494function NumberToJSON_(value) {
sgjesse@chromium.org715915b2009-01-19 16:08:47 +00002495 if (isNaN(value)) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002496 return 'NaN';
sgjesse@chromium.org715915b2009-01-19 16:08:47 +00002497 }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002498 if (!NUMBER_IS_FINITE(value)) {
sgjesse@chromium.org715915b2009-01-19 16:08:47 +00002499 if (value > 0) {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002500 return 'Infinity';
sgjesse@chromium.org715915b2009-01-19 16:08:47 +00002501 } else {
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +00002502 return '-Infinity';
sgjesse@chromium.org715915b2009-01-19 16:08:47 +00002503 }
2504 }
lrn@chromium.org25156de2010-04-06 13:10:27 +00002505 return value;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +00002506}