Home | History | Annotate | Download | only in debug
      1 // Copyright 2006-2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 (function(global, utils) {
      6 "use strict";
      7 
      8 // ----------------------------------------------------------------------------
      9 // Imports
     10 
     11 var GlobalArray = global.Array;
     12 var IsNaN = global.isNaN;
     13 var JSONStringify = global.JSON.stringify;
     14 var MapEntries;
     15 var MapIteratorNext;
     16 var SetIteratorNext;
     17 var SetValues;
     18 
     19 utils.Import(function(from) {
     20   MapEntries = from.MapEntries;
     21   MapIteratorNext = from.MapIteratorNext;
     22   SetIteratorNext = from.SetIteratorNext;
     23   SetValues = from.SetValues;
     24 });
     25 
     26 // ----------------------------------------------------------------------------
     27 
     28 // Mirror hierarchy:
     29 // - Mirror
     30 //   - ValueMirror
     31 //     - UndefinedMirror
     32 //     - NullMirror
     33 //     - BooleanMirror
     34 //     - NumberMirror
     35 //     - StringMirror
     36 //     - SymbolMirror
     37 //     - ObjectMirror
     38 //       - FunctionMirror
     39 //         - UnresolvedFunctionMirror
     40 //       - ArrayMirror
     41 //       - DateMirror
     42 //       - RegExpMirror
     43 //       - ErrorMirror
     44 //       - PromiseMirror
     45 //       - MapMirror
     46 //       - SetMirror
     47 //       - IteratorMirror
     48 //       - GeneratorMirror
     49 //   - PropertyMirror
     50 //   - InternalPropertyMirror
     51 //   - FrameMirror
     52 //   - ScriptMirror
     53 //   - ScopeMirror
     54 
     55 // Type names of the different mirrors.
     56 var MirrorType = {
     57   UNDEFINED_TYPE : 'undefined',
     58   NULL_TYPE : 'null',
     59   BOOLEAN_TYPE : 'boolean',
     60   NUMBER_TYPE : 'number',
     61   STRING_TYPE : 'string',
     62   SYMBOL_TYPE : 'symbol',
     63   OBJECT_TYPE : 'object',
     64   FUNCTION_TYPE : 'function',
     65   REGEXP_TYPE : 'regexp',
     66   ERROR_TYPE : 'error',
     67   PROPERTY_TYPE : 'property',
     68   INTERNAL_PROPERTY_TYPE : 'internalProperty',
     69   FRAME_TYPE : 'frame',
     70   SCRIPT_TYPE : 'script',
     71   CONTEXT_TYPE : 'context',
     72   SCOPE_TYPE : 'scope',
     73   PROMISE_TYPE : 'promise',
     74   MAP_TYPE : 'map',
     75   SET_TYPE : 'set',
     76   ITERATOR_TYPE : 'iterator',
     77   GENERATOR_TYPE : 'generator',
     78 }
     79 
     80 /**
     81  * Returns the mirror for a specified value or object.
     82  *
     83  * @param {value or Object} value the value or object to retrieve the mirror for
     84  * @returns {Mirror} the mirror reflects the passed value or object
     85  */
     86 function MakeMirror(value) {
     87   var mirror;
     88 
     89   if (IS_UNDEFINED(value)) {
     90     mirror = new UndefinedMirror();
     91   } else if (IS_NULL(value)) {
     92     mirror = new NullMirror();
     93   } else if (IS_BOOLEAN(value)) {
     94     mirror = new BooleanMirror(value);
     95   } else if (IS_NUMBER(value)) {
     96     mirror = new NumberMirror(value);
     97   } else if (IS_STRING(value)) {
     98     mirror = new StringMirror(value);
     99   } else if (IS_SYMBOL(value)) {
    100     mirror = new SymbolMirror(value);
    101   } else if (IS_ARRAY(value)) {
    102     mirror = new ArrayMirror(value);
    103   } else if (IS_DATE(value)) {
    104     mirror = new DateMirror(value);
    105   } else if (IS_FUNCTION(value)) {
    106     mirror = new FunctionMirror(value);
    107   } else if (%IsRegExp(value)) {
    108     mirror = new RegExpMirror(value);
    109   } else if (IS_ERROR(value)) {
    110     mirror = new ErrorMirror(value);
    111   } else if (IS_SCRIPT(value)) {
    112     mirror = new ScriptMirror(value);
    113   } else if (IS_MAP(value) || IS_WEAKMAP(value)) {
    114     mirror = new MapMirror(value);
    115   } else if (IS_SET(value) || IS_WEAKSET(value)) {
    116     mirror = new SetMirror(value);
    117   } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) {
    118     mirror = new IteratorMirror(value);
    119   } else if (%is_promise(value)) {
    120     mirror = new PromiseMirror(value);
    121   } else if (IS_GENERATOR(value)) {
    122     mirror = new GeneratorMirror(value);
    123   } else {
    124     mirror = new ObjectMirror(value, MirrorType.OBJECT_TYPE);
    125   }
    126 
    127   return mirror;
    128 }
    129 
    130 
    131 /**
    132  * Returns the mirror for the undefined value.
    133  *
    134  * @returns {Mirror} the mirror reflects the undefined value
    135  */
    136 function GetUndefinedMirror() {
    137   return MakeMirror(UNDEFINED);
    138 }
    139 
    140 
    141 /**
    142  * Inherit the prototype methods from one constructor into another.
    143  *
    144  * The Function.prototype.inherits from lang.js rewritten as a standalone
    145  * function (not on Function.prototype). NOTE: If this file is to be loaded
    146  * during bootstrapping this function needs to be revritten using some native
    147  * functions as prototype setup using normal JavaScript does not work as
    148  * expected during bootstrapping (see mirror.js in r114903).
    149  *
    150  * @param {function} ctor Constructor function which needs to inherit the
    151  *     prototype
    152  * @param {function} superCtor Constructor function to inherit prototype from
    153  */
    154 function inherits(ctor, superCtor) {
    155   var tempCtor = function(){};
    156   tempCtor.prototype = superCtor.prototype;
    157   ctor.super_ = superCtor.prototype;
    158   ctor.prototype = new tempCtor();
    159   ctor.prototype.constructor = ctor;
    160 }
    161 
    162 // Maximum length when sending strings through the JSON protocol.
    163 var kMaxProtocolStringLength = 80;
    164 
    165 
    166 // A copy of the PropertyKind enum from property-details.h
    167 var PropertyType = {};
    168 PropertyType.Data     = 0;
    169 PropertyType.Accessor = 1;
    170 
    171 
    172 // Different attributes for a property.
    173 var PropertyAttribute = {};
    174 PropertyAttribute.None       = NONE;
    175 PropertyAttribute.ReadOnly   = READ_ONLY;
    176 PropertyAttribute.DontEnum   = DONT_ENUM;
    177 PropertyAttribute.DontDelete = DONT_DELETE;
    178 
    179 
    180 // A copy of the scope types from runtime-debug.cc.
    181 // NOTE: these constants should be backward-compatible, so
    182 // add new ones to the end of this list.
    183 var ScopeType = { Global:  0,
    184                   Local:   1,
    185                   With:    2,
    186                   Closure: 3,
    187                   Catch:   4,
    188                   Block:   5,
    189                   Script:  6,
    190                   Eval:    7,
    191                   Module:  8,
    192                 };
    193 
    194 /**
    195  * Base class for all mirror objects.
    196  * @param {string} type The type of the mirror
    197  * @constructor
    198  */
    199 function Mirror(type) {
    200   this.type_ = type;
    201 }
    202 
    203 
    204 Mirror.prototype.type = function() {
    205   return this.type_;
    206 };
    207 
    208 
    209 /**
    210  * Check whether the mirror reflects a value.
    211  * @returns {boolean} True if the mirror reflects a value.
    212  */
    213 Mirror.prototype.isValue = function() {
    214   return this instanceof ValueMirror;
    215 };
    216 
    217 
    218 /**
    219  * Check whether the mirror reflects the undefined value.
    220  * @returns {boolean} True if the mirror reflects the undefined value.
    221  */
    222 Mirror.prototype.isUndefined = function() {
    223   return this instanceof UndefinedMirror;
    224 };
    225 
    226 
    227 /**
    228  * Check whether the mirror reflects the null value.
    229  * @returns {boolean} True if the mirror reflects the null value
    230  */
    231 Mirror.prototype.isNull = function() {
    232   return this instanceof NullMirror;
    233 };
    234 
    235 
    236 /**
    237  * Check whether the mirror reflects a boolean value.
    238  * @returns {boolean} True if the mirror reflects a boolean value
    239  */
    240 Mirror.prototype.isBoolean = function() {
    241   return this instanceof BooleanMirror;
    242 };
    243 
    244 
    245 /**
    246  * Check whether the mirror reflects a number value.
    247  * @returns {boolean} True if the mirror reflects a number value
    248  */
    249 Mirror.prototype.isNumber = function() {
    250   return this instanceof NumberMirror;
    251 };
    252 
    253 
    254 /**
    255  * Check whether the mirror reflects a string value.
    256  * @returns {boolean} True if the mirror reflects a string value
    257  */
    258 Mirror.prototype.isString = function() {
    259   return this instanceof StringMirror;
    260 };
    261 
    262 
    263 /**
    264  * Check whether the mirror reflects a symbol.
    265  * @returns {boolean} True if the mirror reflects a symbol
    266  */
    267 Mirror.prototype.isSymbol = function() {
    268   return this instanceof SymbolMirror;
    269 };
    270 
    271 
    272 /**
    273  * Check whether the mirror reflects an object.
    274  * @returns {boolean} True if the mirror reflects an object
    275  */
    276 Mirror.prototype.isObject = function() {
    277   return this instanceof ObjectMirror;
    278 };
    279 
    280 
    281 /**
    282  * Check whether the mirror reflects a function.
    283  * @returns {boolean} True if the mirror reflects a function
    284  */
    285 Mirror.prototype.isFunction = function() {
    286   return this instanceof FunctionMirror;
    287 };
    288 
    289 
    290 /**
    291  * Check whether the mirror reflects an unresolved function.
    292  * @returns {boolean} True if the mirror reflects an unresolved function
    293  */
    294 Mirror.prototype.isUnresolvedFunction = function() {
    295   return this instanceof UnresolvedFunctionMirror;
    296 };
    297 
    298 
    299 /**
    300  * Check whether the mirror reflects an array.
    301  * @returns {boolean} True if the mirror reflects an array
    302  */
    303 Mirror.prototype.isArray = function() {
    304   return this instanceof ArrayMirror;
    305 };
    306 
    307 
    308 /**
    309  * Check whether the mirror reflects a date.
    310  * @returns {boolean} True if the mirror reflects a date
    311  */
    312 Mirror.prototype.isDate = function() {
    313   return this instanceof DateMirror;
    314 };
    315 
    316 
    317 /**
    318  * Check whether the mirror reflects a regular expression.
    319  * @returns {boolean} True if the mirror reflects a regular expression
    320  */
    321 Mirror.prototype.isRegExp = function() {
    322   return this instanceof RegExpMirror;
    323 };
    324 
    325 
    326 /**
    327  * Check whether the mirror reflects an error.
    328  * @returns {boolean} True if the mirror reflects an error
    329  */
    330 Mirror.prototype.isError = function() {
    331   return this instanceof ErrorMirror;
    332 };
    333 
    334 
    335 /**
    336  * Check whether the mirror reflects a promise.
    337  * @returns {boolean} True if the mirror reflects a promise
    338  */
    339 Mirror.prototype.isPromise = function() {
    340   return this instanceof PromiseMirror;
    341 };
    342 
    343 
    344 /**
    345  * Check whether the mirror reflects a generator object.
    346  * @returns {boolean} True if the mirror reflects a generator object
    347  */
    348 Mirror.prototype.isGenerator = function() {
    349   return this instanceof GeneratorMirror;
    350 };
    351 
    352 
    353 /**
    354  * Check whether the mirror reflects a property.
    355  * @returns {boolean} True if the mirror reflects a property
    356  */
    357 Mirror.prototype.isProperty = function() {
    358   return this instanceof PropertyMirror;
    359 };
    360 
    361 
    362 /**
    363  * Check whether the mirror reflects an internal property.
    364  * @returns {boolean} True if the mirror reflects an internal property
    365  */
    366 Mirror.prototype.isInternalProperty = function() {
    367   return this instanceof InternalPropertyMirror;
    368 };
    369 
    370 
    371 /**
    372  * Check whether the mirror reflects a stack frame.
    373  * @returns {boolean} True if the mirror reflects a stack frame
    374  */
    375 Mirror.prototype.isFrame = function() {
    376   return this instanceof FrameMirror;
    377 };
    378 
    379 
    380 /**
    381  * Check whether the mirror reflects a script.
    382  * @returns {boolean} True if the mirror reflects a script
    383  */
    384 Mirror.prototype.isScript = function() {
    385   return this instanceof ScriptMirror;
    386 };
    387 
    388 
    389 /**
    390  * Check whether the mirror reflects a context.
    391  * @returns {boolean} True if the mirror reflects a context
    392  */
    393 Mirror.prototype.isContext = function() {
    394   return this instanceof ContextMirror;
    395 };
    396 
    397 
    398 /**
    399  * Check whether the mirror reflects a scope.
    400  * @returns {boolean} True if the mirror reflects a scope
    401  */
    402 Mirror.prototype.isScope = function() {
    403   return this instanceof ScopeMirror;
    404 };
    405 
    406 
    407 /**
    408  * Check whether the mirror reflects a map.
    409  * @returns {boolean} True if the mirror reflects a map
    410  */
    411 Mirror.prototype.isMap = function() {
    412   return this instanceof MapMirror;
    413 };
    414 
    415 
    416 /**
    417  * Check whether the mirror reflects a set.
    418  * @returns {boolean} True if the mirror reflects a set
    419  */
    420 Mirror.prototype.isSet = function() {
    421   return this instanceof SetMirror;
    422 };
    423 
    424 
    425 /**
    426  * Check whether the mirror reflects an iterator.
    427  * @returns {boolean} True if the mirror reflects an iterator
    428  */
    429 Mirror.prototype.isIterator = function() {
    430   return this instanceof IteratorMirror;
    431 };
    432 
    433 
    434 Mirror.prototype.toText = function() {
    435   // Simpel to text which is used when on specialization in subclass.
    436   return "#<" + this.constructor.name + ">";
    437 };
    438 
    439 
    440 /**
    441  * Base class for all value mirror objects.
    442  * @param {string} type The type of the mirror
    443  * @param {value} value The value reflected by this mirror
    444  * @constructor
    445  * @extends Mirror
    446  */
    447 function ValueMirror(type, value) {
    448   %_Call(Mirror, this, type);
    449   this.value_ = value;
    450 }
    451 inherits(ValueMirror, Mirror);
    452 
    453 
    454 /**
    455  * Check whether this is a primitive value.
    456  * @return {boolean} True if the mirror reflects a primitive value
    457  */
    458 ValueMirror.prototype.isPrimitive = function() {
    459   var type = this.type();
    460   return type === 'undefined' ||
    461          type === 'null' ||
    462          type === 'boolean' ||
    463          type === 'number' ||
    464          type === 'string' ||
    465          type === 'symbol';
    466 };
    467 
    468 
    469 /**
    470  * Get the actual value reflected by this mirror.
    471  * @return {value} The value reflected by this mirror
    472  */
    473 ValueMirror.prototype.value = function() {
    474   return this.value_;
    475 };
    476 
    477 
    478 /**
    479  * Mirror object for Undefined.
    480  * @constructor
    481  * @extends ValueMirror
    482  */
    483 function UndefinedMirror() {
    484   %_Call(ValueMirror, this, MirrorType.UNDEFINED_TYPE, UNDEFINED);
    485 }
    486 inherits(UndefinedMirror, ValueMirror);
    487 
    488 
    489 UndefinedMirror.prototype.toText = function() {
    490   return 'undefined';
    491 };
    492 
    493 
    494 /**
    495  * Mirror object for null.
    496  * @constructor
    497  * @extends ValueMirror
    498  */
    499 function NullMirror() {
    500   %_Call(ValueMirror, this, MirrorType.NULL_TYPE, null);
    501 }
    502 inherits(NullMirror, ValueMirror);
    503 
    504 
    505 NullMirror.prototype.toText = function() {
    506   return 'null';
    507 };
    508 
    509 
    510 /**
    511  * Mirror object for boolean values.
    512  * @param {boolean} value The boolean value reflected by this mirror
    513  * @constructor
    514  * @extends ValueMirror
    515  */
    516 function BooleanMirror(value) {
    517   %_Call(ValueMirror, this, MirrorType.BOOLEAN_TYPE, value);
    518 }
    519 inherits(BooleanMirror, ValueMirror);
    520 
    521 
    522 BooleanMirror.prototype.toText = function() {
    523   return this.value_ ? 'true' : 'false';
    524 };
    525 
    526 
    527 /**
    528  * Mirror object for number values.
    529  * @param {number} value The number value reflected by this mirror
    530  * @constructor
    531  * @extends ValueMirror
    532  */
    533 function NumberMirror(value) {
    534   %_Call(ValueMirror, this, MirrorType.NUMBER_TYPE, value);
    535 }
    536 inherits(NumberMirror, ValueMirror);
    537 
    538 
    539 NumberMirror.prototype.toText = function() {
    540   return %NumberToString(this.value_);
    541 };
    542 
    543 
    544 /**
    545  * Mirror object for string values.
    546  * @param {string} value The string value reflected by this mirror
    547  * @constructor
    548  * @extends ValueMirror
    549  */
    550 function StringMirror(value) {
    551   %_Call(ValueMirror, this, MirrorType.STRING_TYPE, value);
    552 }
    553 inherits(StringMirror, ValueMirror);
    554 
    555 
    556 StringMirror.prototype.length = function() {
    557   return this.value_.length;
    558 };
    559 
    560 StringMirror.prototype.getTruncatedValue = function(maxLength) {
    561   if (maxLength != -1 && this.length() > maxLength) {
    562     return this.value_.substring(0, maxLength) +
    563            '... (length: ' + this.length() + ')';
    564   }
    565   return this.value_;
    566 };
    567 
    568 StringMirror.prototype.toText = function() {
    569   return this.getTruncatedValue(kMaxProtocolStringLength);
    570 };
    571 
    572 
    573 /**
    574  * Mirror object for a Symbol
    575  * @param {Object} value The Symbol
    576  * @constructor
    577  * @extends Mirror
    578  */
    579 function SymbolMirror(value) {
    580   %_Call(ValueMirror, this, MirrorType.SYMBOL_TYPE, value);
    581 }
    582 inherits(SymbolMirror, ValueMirror);
    583 
    584 
    585 SymbolMirror.prototype.description = function() {
    586   return %SymbolDescription(%ValueOf(this.value_));
    587 }
    588 
    589 
    590 SymbolMirror.prototype.toText = function() {
    591   return %SymbolDescriptiveString(%ValueOf(this.value_));
    592 }
    593 
    594 
    595 /**
    596  * Mirror object for objects.
    597  * @param {object} value The object reflected by this mirror
    598  * @constructor
    599  * @extends ValueMirror
    600  */
    601 function ObjectMirror(value, type) {
    602   type = type || MirrorType.OBJECT_TYPE;
    603   %_Call(ValueMirror, this, type, value);
    604 }
    605 inherits(ObjectMirror, ValueMirror);
    606 
    607 
    608 ObjectMirror.prototype.className = function() {
    609   return %_ClassOf(this.value_);
    610 };
    611 
    612 
    613 ObjectMirror.prototype.constructorFunction = function() {
    614   return MakeMirror(%DebugGetProperty(this.value_, 'constructor'));
    615 };
    616 
    617 
    618 ObjectMirror.prototype.prototypeObject = function() {
    619   return MakeMirror(%DebugGetProperty(this.value_, 'prototype'));
    620 };
    621 
    622 
    623 ObjectMirror.prototype.protoObject = function() {
    624   return MakeMirror(%DebugGetPrototype(this.value_));
    625 };
    626 
    627 
    628 ObjectMirror.prototype.hasNamedInterceptor = function() {
    629   // Get information on interceptors for this object.
    630   var x = %GetInterceptorInfo(this.value_);
    631   return (x & 2) != 0;
    632 };
    633 
    634 
    635 ObjectMirror.prototype.hasIndexedInterceptor = function() {
    636   // Get information on interceptors for this object.
    637   var x = %GetInterceptorInfo(this.value_);
    638   return (x & 1) != 0;
    639 };
    640 
    641 
    642 /**
    643  * Return the property names for this object.
    644  * @param {number} kind Indicate whether named, indexed or both kinds of
    645  *     properties are requested
    646  * @param {number} limit Limit the number of names returend to the specified
    647        value
    648  * @return {Array} Property names for this object
    649  */
    650 ObjectMirror.prototype.propertyNames = function() {
    651   return %GetOwnPropertyKeys(this.value_, PROPERTY_FILTER_NONE);
    652 };
    653 
    654 
    655 /**
    656  * Return the properties for this object as an array of PropertyMirror objects.
    657  * @param {number} kind Indicate whether named, indexed or both kinds of
    658  *     properties are requested
    659  * @param {number} limit Limit the number of properties returned to the
    660        specified value
    661  * @return {Array} Property mirrors for this object
    662  */
    663 ObjectMirror.prototype.properties = function() {
    664   var names = this.propertyNames();
    665   var properties = new GlobalArray(names.length);
    666   for (var i = 0; i < names.length; i++) {
    667     properties[i] = this.property(names[i]);
    668   }
    669 
    670   return properties;
    671 };
    672 
    673 
    674 /**
    675  * Return the internal properties for this object as an array of
    676  * InternalPropertyMirror objects.
    677  * @return {Array} Property mirrors for this object
    678  */
    679 ObjectMirror.prototype.internalProperties = function() {
    680   return ObjectMirror.GetInternalProperties(this.value_);
    681 }
    682 
    683 
    684 ObjectMirror.prototype.property = function(name) {
    685   var details = %DebugGetPropertyDetails(this.value_, name);
    686   if (details) {
    687     return new PropertyMirror(this, name, details);
    688   }
    689 
    690   // Nothing found.
    691   return GetUndefinedMirror();
    692 };
    693 
    694 
    695 
    696 /**
    697  * Try to find a property from its value.
    698  * @param {Mirror} value The property value to look for
    699  * @return {PropertyMirror} The property with the specified value. If no
    700  *     property was found with the specified value UndefinedMirror is returned
    701  */
    702 ObjectMirror.prototype.lookupProperty = function(value) {
    703   var properties = this.properties();
    704 
    705   // Look for property value in properties.
    706   for (var i = 0; i < properties.length; i++) {
    707 
    708     // Skip properties which are defined through accessors.
    709     var property = properties[i];
    710     if (property.propertyType() == PropertyType.Data) {
    711       if (property.value_ === value.value_) {
    712         return property;
    713       }
    714     }
    715   }
    716 
    717   // Nothing found.
    718   return GetUndefinedMirror();
    719 };
    720 
    721 
    722 /**
    723  * Returns objects which has direct references to this object
    724  * @param {number} opt_max_objects Optional parameter specifying the maximum
    725  *     number of referencing objects to return.
    726  * @return {Array} The objects which has direct references to this object.
    727  */
    728 ObjectMirror.prototype.referencedBy = function(opt_max_objects) {
    729   // Find all objects with direct references to this object.
    730   var result = %DebugReferencedBy(this.value_,
    731                                   Mirror.prototype, opt_max_objects || 0);
    732 
    733   // Make mirrors for all the references found.
    734   for (var i = 0; i < result.length; i++) {
    735     result[i] = MakeMirror(result[i]);
    736   }
    737 
    738   return result;
    739 };
    740 
    741 
    742 ObjectMirror.prototype.toText = function() {
    743   var name;
    744   var ctor = this.constructorFunction();
    745   if (!ctor.isFunction()) {
    746     name = this.className();
    747   } else {
    748     name = ctor.name();
    749     if (!name) {
    750       name = this.className();
    751     }
    752   }
    753   return '#<' + name + '>';
    754 };
    755 
    756 
    757 /**
    758  * Return the internal properties of the value, such as [[PrimitiveValue]] of
    759  * scalar wrapper objects, properties of the bound function and properties of
    760  * the promise.
    761  * This method is done static to be accessible from Debug API with the bare
    762  * values without mirrors.
    763  * @return {Array} array (possibly empty) of InternalProperty instances
    764  */
    765 ObjectMirror.GetInternalProperties = function(value) {
    766   var properties = %DebugGetInternalProperties(value);
    767   var result = [];
    768   for (var i = 0; i < properties.length; i += 2) {
    769     result.push(new InternalPropertyMirror(properties[i], properties[i + 1]));
    770   }
    771   return result;
    772 }
    773 
    774 
    775 /**
    776  * Mirror object for functions.
    777  * @param {function} value The function object reflected by this mirror.
    778  * @constructor
    779  * @extends ObjectMirror
    780  */
    781 function FunctionMirror(value) {
    782   %_Call(ObjectMirror, this, value, MirrorType.FUNCTION_TYPE);
    783   this.resolved_ = true;
    784 }
    785 inherits(FunctionMirror, ObjectMirror);
    786 
    787 
    788 /**
    789  * Returns whether the function is resolved.
    790  * @return {boolean} True if the function is resolved. Unresolved functions can
    791  *     only originate as functions from stack frames
    792  */
    793 FunctionMirror.prototype.resolved = function() {
    794   return this.resolved_;
    795 };
    796 
    797 
    798 /**
    799  * Returns the name of the function.
    800  * @return {string} Name of the function
    801  */
    802 FunctionMirror.prototype.name = function() {
    803   return %FunctionGetName(this.value_);
    804 };
    805 
    806 
    807 /**
    808  * Returns the displayName if it is set, otherwise name, otherwise inferred
    809  * name.
    810  * @return {string} Name of the function
    811  */
    812 FunctionMirror.prototype.debugName = function() {
    813   return %FunctionGetDebugName(this.value_);
    814 }
    815 
    816 
    817 /**
    818  * Returns the inferred name of the function.
    819  * @return {string} Name of the function
    820  */
    821 FunctionMirror.prototype.inferredName = function() {
    822   return %FunctionGetInferredName(this.value_);
    823 };
    824 
    825 
    826 /**
    827  * Returns the source code for the function.
    828  * @return {string or undefined} The source code for the function. If the
    829  *     function is not resolved undefined will be returned.
    830  */
    831 FunctionMirror.prototype.source = function() {
    832   // Return source if function is resolved. Otherwise just fall through to
    833   // return undefined.
    834   if (this.resolved()) {
    835     return %FunctionToString(this.value_);
    836   }
    837 };
    838 
    839 
    840 /**
    841  * Returns the script object for the function.
    842  * @return {ScriptMirror or undefined} Script object for the function or
    843  *     undefined if the function has no script
    844  */
    845 FunctionMirror.prototype.script = function() {
    846   // Return script if function is resolved. Otherwise just fall through
    847   // to return undefined.
    848   if (this.resolved()) {
    849     if (this.script_) {
    850       return this.script_;
    851     }
    852     var script = %FunctionGetScript(this.value_);
    853     if (script) {
    854       return this.script_ = MakeMirror(script);
    855     }
    856   }
    857 };
    858 
    859 
    860 /**
    861  * Returns the script source position for the function. Only makes sense
    862  * for functions which has a script defined.
    863  * @return {Number or undefined} in-script position for the function
    864  */
    865 FunctionMirror.prototype.sourcePosition_ = function() {
    866   // Return position if function is resolved. Otherwise just fall
    867   // through to return undefined.
    868   if (this.resolved()) {
    869     return %FunctionGetScriptSourcePosition(this.value_);
    870   }
    871 };
    872 
    873 
    874 /**
    875  * Returns the script source location object for the function. Only makes sense
    876  * for functions which has a script defined.
    877  * @return {Location or undefined} in-script location for the function begin
    878  */
    879 FunctionMirror.prototype.sourceLocation = function() {
    880   if (this.resolved()) {
    881     var script = this.script();
    882     if (script) {
    883       return script.locationFromPosition(this.sourcePosition_(), true);
    884     }
    885   }
    886 };
    887 
    888 
    889 /**
    890  * Returns objects constructed by this function.
    891  * @param {number} opt_max_instances Optional parameter specifying the maximum
    892  *     number of instances to return.
    893  * @return {Array or undefined} The objects constructed by this function.
    894  */
    895 FunctionMirror.prototype.constructedBy = function(opt_max_instances) {
    896   if (this.resolved()) {
    897     // Find all objects constructed from this function.
    898     var result = %DebugConstructedBy(this.value_, opt_max_instances || 0);
    899 
    900     // Make mirrors for all the instances found.
    901     for (var i = 0; i < result.length; i++) {
    902       result[i] = MakeMirror(result[i]);
    903     }
    904 
    905     return result;
    906   } else {
    907     return [];
    908   }
    909 };
    910 
    911 
    912 FunctionMirror.prototype.scopeCount = function() {
    913   if (this.resolved()) {
    914     if (IS_UNDEFINED(this.scopeCount_)) {
    915       this.scopeCount_ = %GetFunctionScopeCount(this.value());
    916     }
    917     return this.scopeCount_;
    918   } else {
    919     return 0;
    920   }
    921 };
    922 
    923 
    924 FunctionMirror.prototype.scope = function(index) {
    925   if (this.resolved()) {
    926     return new ScopeMirror(UNDEFINED, this, UNDEFINED, index);
    927   }
    928 };
    929 
    930 
    931 FunctionMirror.prototype.toText = function() {
    932   return this.source();
    933 };
    934 
    935 
    936 FunctionMirror.prototype.context = function() {
    937   if (this.resolved()) {
    938     if (!this._context)
    939       this._context = new ContextMirror(%FunctionGetContextData(this.value_));
    940     return this._context;
    941   }
    942 };
    943 
    944 
    945 /**
    946  * Mirror object for unresolved functions.
    947  * @param {string} value The name for the unresolved function reflected by this
    948  *     mirror.
    949  * @constructor
    950  * @extends ObjectMirror
    951  */
    952 function UnresolvedFunctionMirror(value) {
    953   // Construct this using the ValueMirror as an unresolved function is not a
    954   // real object but just a string.
    955   %_Call(ValueMirror, this, MirrorType.FUNCTION_TYPE, value);
    956   this.propertyCount_ = 0;
    957   this.elementCount_ = 0;
    958   this.resolved_ = false;
    959 }
    960 inherits(UnresolvedFunctionMirror, FunctionMirror);
    961 
    962 
    963 UnresolvedFunctionMirror.prototype.className = function() {
    964   return 'Function';
    965 };
    966 
    967 
    968 UnresolvedFunctionMirror.prototype.constructorFunction = function() {
    969   return GetUndefinedMirror();
    970 };
    971 
    972 
    973 UnresolvedFunctionMirror.prototype.prototypeObject = function() {
    974   return GetUndefinedMirror();
    975 };
    976 
    977 
    978 UnresolvedFunctionMirror.prototype.protoObject = function() {
    979   return GetUndefinedMirror();
    980 };
    981 
    982 
    983 UnresolvedFunctionMirror.prototype.name = function() {
    984   return this.value_;
    985 };
    986 
    987 
    988 UnresolvedFunctionMirror.prototype.debugName = function() {
    989   return this.value_;
    990 };
    991 
    992 
    993 UnresolvedFunctionMirror.prototype.inferredName = function() {
    994   return UNDEFINED;
    995 };
    996 
    997 
    998 UnresolvedFunctionMirror.prototype.propertyNames = function(kind, limit) {
    999   return [];
   1000 };
   1001 
   1002 
   1003 /**
   1004  * Mirror object for arrays.
   1005  * @param {Array} value The Array object reflected by this mirror
   1006  * @constructor
   1007  * @extends ObjectMirror
   1008  */
   1009 function ArrayMirror(value) {
   1010   %_Call(ObjectMirror, this, value);
   1011 }
   1012 inherits(ArrayMirror, ObjectMirror);
   1013 
   1014 
   1015 ArrayMirror.prototype.length = function() {
   1016   return this.value_.length;
   1017 };
   1018 
   1019 
   1020 ArrayMirror.prototype.indexedPropertiesFromRange = function(opt_from_index,
   1021                                                             opt_to_index) {
   1022   var from_index = opt_from_index || 0;
   1023   var to_index = opt_to_index || this.length() - 1;
   1024   if (from_index > to_index) return new GlobalArray();
   1025   var values = new GlobalArray(to_index - from_index + 1);
   1026   for (var i = from_index; i <= to_index; i++) {
   1027     var details = %DebugGetPropertyDetails(this.value_, TO_STRING(i));
   1028     var value;
   1029     if (details) {
   1030       value = new PropertyMirror(this, i, details);
   1031     } else {
   1032       value = GetUndefinedMirror();
   1033     }
   1034     values[i - from_index] = value;
   1035   }
   1036   return values;
   1037 };
   1038 
   1039 
   1040 /**
   1041  * Mirror object for dates.
   1042  * @param {Date} value The Date object reflected by this mirror
   1043  * @constructor
   1044  * @extends ObjectMirror
   1045  */
   1046 function DateMirror(value) {
   1047   %_Call(ObjectMirror, this, value);
   1048 }
   1049 inherits(DateMirror, ObjectMirror);
   1050 
   1051 
   1052 DateMirror.prototype.toText = function() {
   1053   var s = JSONStringify(this.value_);
   1054   return s.substring(1, s.length - 1);  // cut quotes
   1055 };
   1056 
   1057 
   1058 /**
   1059  * Mirror object for regular expressions.
   1060  * @param {RegExp} value The RegExp object reflected by this mirror
   1061  * @constructor
   1062  * @extends ObjectMirror
   1063  */
   1064 function RegExpMirror(value) {
   1065   %_Call(ObjectMirror, this, value, MirrorType.REGEXP_TYPE);
   1066 }
   1067 inherits(RegExpMirror, ObjectMirror);
   1068 
   1069 
   1070 /**
   1071  * Returns the source to the regular expression.
   1072  * @return {string or undefined} The source to the regular expression
   1073  */
   1074 RegExpMirror.prototype.source = function() {
   1075   return this.value_.source;
   1076 };
   1077 
   1078 
   1079 /**
   1080  * Returns whether this regular expression has the global (g) flag set.
   1081  * @return {boolean} Value of the global flag
   1082  */
   1083 RegExpMirror.prototype.global = function() {
   1084   return this.value_.global;
   1085 };
   1086 
   1087 
   1088 /**
   1089  * Returns whether this regular expression has the ignore case (i) flag set.
   1090  * @return {boolean} Value of the ignore case flag
   1091  */
   1092 RegExpMirror.prototype.ignoreCase = function() {
   1093   return this.value_.ignoreCase;
   1094 };
   1095 
   1096 
   1097 /**
   1098  * Returns whether this regular expression has the multiline (m) flag set.
   1099  * @return {boolean} Value of the multiline flag
   1100  */
   1101 RegExpMirror.prototype.multiline = function() {
   1102   return this.value_.multiline;
   1103 };
   1104 
   1105 
   1106 /**
   1107  * Returns whether this regular expression has the sticky (y) flag set.
   1108  * @return {boolean} Value of the sticky flag
   1109  */
   1110 RegExpMirror.prototype.sticky = function() {
   1111   return this.value_.sticky;
   1112 };
   1113 
   1114 
   1115 /**
   1116  * Returns whether this regular expression has the unicode (u) flag set.
   1117  * @return {boolean} Value of the unicode flag
   1118  */
   1119 RegExpMirror.prototype.unicode = function() {
   1120   return this.value_.unicode;
   1121 };
   1122 
   1123 
   1124 RegExpMirror.prototype.toText = function() {
   1125   // Simpel to text which is used when on specialization in subclass.
   1126   return "/" + this.source() + "/";
   1127 };
   1128 
   1129 
   1130 /**
   1131  * Mirror object for error objects.
   1132  * @param {Error} value The error object reflected by this mirror
   1133  * @constructor
   1134  * @extends ObjectMirror
   1135  */
   1136 function ErrorMirror(value) {
   1137   %_Call(ObjectMirror, this, value, MirrorType.ERROR_TYPE);
   1138 }
   1139 inherits(ErrorMirror, ObjectMirror);
   1140 
   1141 
   1142 /**
   1143  * Returns the message for this eror object.
   1144  * @return {string or undefined} The message for this eror object
   1145  */
   1146 ErrorMirror.prototype.message = function() {
   1147   return this.value_.message;
   1148 };
   1149 
   1150 
   1151 ErrorMirror.prototype.toText = function() {
   1152   // Use the same text representation as in messages.js.
   1153   var text;
   1154   try {
   1155     text = %ErrorToString(this.value_);
   1156   } catch (e) {
   1157     text = '#<Error>';
   1158   }
   1159   return text;
   1160 };
   1161 
   1162 
   1163 /**
   1164  * Mirror object for a Promise object.
   1165  * @param {Object} value The Promise object
   1166  * @constructor
   1167  * @extends ObjectMirror
   1168  */
   1169 function PromiseMirror(value) {
   1170   %_Call(ObjectMirror, this, value, MirrorType.PROMISE_TYPE);
   1171 }
   1172 inherits(PromiseMirror, ObjectMirror);
   1173 
   1174 
   1175 function PromiseGetStatus_(value) {
   1176   var status = %PromiseStatus(value);
   1177   if (status == 0) return "pending";
   1178   if (status == 1) return "resolved";
   1179   return "rejected";
   1180 }
   1181 
   1182 
   1183 function PromiseGetValue_(value) {
   1184   return %PromiseResult(value);
   1185 }
   1186 
   1187 
   1188 PromiseMirror.prototype.status = function() {
   1189   return PromiseGetStatus_(this.value_);
   1190 };
   1191 
   1192 
   1193 PromiseMirror.prototype.promiseValue = function() {
   1194   return MakeMirror(PromiseGetValue_(this.value_));
   1195 };
   1196 
   1197 
   1198 function MapMirror(value) {
   1199   %_Call(ObjectMirror, this, value, MirrorType.MAP_TYPE);
   1200 }
   1201 inherits(MapMirror, ObjectMirror);
   1202 
   1203 
   1204 /**
   1205  * Returns an array of key/value pairs of a map.
   1206  * This will keep keys alive for WeakMaps.
   1207  *
   1208  * @param {number=} opt_limit Max elements to return.
   1209  * @returns {Array.<Object>} Array of key/value pairs of a map.
   1210  */
   1211 MapMirror.prototype.entries = function(opt_limit) {
   1212   var result = [];
   1213 
   1214   if (IS_WEAKMAP(this.value_)) {
   1215     var entries = %GetWeakMapEntries(this.value_, opt_limit || 0);
   1216     for (var i = 0; i < entries.length; i += 2) {
   1217       result.push({
   1218         key: entries[i],
   1219         value: entries[i + 1]
   1220       });
   1221     }
   1222     return result;
   1223   }
   1224 
   1225   var iter = %_Call(MapEntries, this.value_);
   1226   var next;
   1227   while ((!opt_limit || result.length < opt_limit) &&
   1228          !(next = iter.next()).done) {
   1229     result.push({
   1230       key: next.value[0],
   1231       value: next.value[1]
   1232     });
   1233   }
   1234   return result;
   1235 };
   1236 
   1237 
   1238 function SetMirror(value) {
   1239   %_Call(ObjectMirror, this, value, MirrorType.SET_TYPE);
   1240 }
   1241 inherits(SetMirror, ObjectMirror);
   1242 
   1243 
   1244 function IteratorGetValues_(iter, next_function, opt_limit) {
   1245   var result = [];
   1246   var next;
   1247   while ((!opt_limit || result.length < opt_limit) &&
   1248          !(next = %_Call(next_function, iter)).done) {
   1249     result.push(next.value);
   1250   }
   1251   return result;
   1252 }
   1253 
   1254 
   1255 /**
   1256  * Returns an array of elements of a set.
   1257  * This will keep elements alive for WeakSets.
   1258  *
   1259  * @param {number=} opt_limit Max elements to return.
   1260  * @returns {Array.<Object>} Array of elements of a set.
   1261  */
   1262 SetMirror.prototype.values = function(opt_limit) {
   1263   if (IS_WEAKSET(this.value_)) {
   1264     return %GetWeakSetValues(this.value_, opt_limit || 0);
   1265   }
   1266 
   1267   var iter = %_Call(SetValues, this.value_);
   1268   return IteratorGetValues_(iter, SetIteratorNext, opt_limit);
   1269 };
   1270 
   1271 
   1272 function IteratorMirror(value) {
   1273   %_Call(ObjectMirror, this, value, MirrorType.ITERATOR_TYPE);
   1274 }
   1275 inherits(IteratorMirror, ObjectMirror);
   1276 
   1277 
   1278 /**
   1279  * Returns a preview of elements of an iterator.
   1280  * Does not change the backing iterator state.
   1281  *
   1282  * @param {number=} opt_limit Max elements to return.
   1283  * @returns {Array.<Object>} Array of elements of an iterator.
   1284  */
   1285 IteratorMirror.prototype.preview = function(opt_limit) {
   1286   if (IS_MAP_ITERATOR(this.value_)) {
   1287     return IteratorGetValues_(%MapIteratorClone(this.value_),
   1288                               MapIteratorNext,
   1289                               opt_limit);
   1290   } else if (IS_SET_ITERATOR(this.value_)) {
   1291     return IteratorGetValues_(%SetIteratorClone(this.value_),
   1292                               SetIteratorNext,
   1293                               opt_limit);
   1294   }
   1295 };
   1296 
   1297 
   1298 /**
   1299  * Mirror object for a Generator object.
   1300  * @param {Object} data The Generator object
   1301  * @constructor
   1302  * @extends Mirror
   1303  */
   1304 function GeneratorMirror(value) {
   1305   %_Call(ObjectMirror, this, value, MirrorType.GENERATOR_TYPE);
   1306 }
   1307 inherits(GeneratorMirror, ObjectMirror);
   1308 
   1309 
   1310 function GeneratorGetStatus_(value) {
   1311   var continuation = %GeneratorGetContinuation(value);
   1312   if (continuation < -1) return "running";
   1313   if (continuation == -1) return "closed";
   1314   return "suspended";
   1315 }
   1316 
   1317 
   1318 GeneratorMirror.prototype.status = function() {
   1319   return GeneratorGetStatus_(this.value_);
   1320 };
   1321 
   1322 
   1323 GeneratorMirror.prototype.sourcePosition_ = function() {
   1324   return %GeneratorGetSourcePosition(this.value_);
   1325 };
   1326 
   1327 
   1328 GeneratorMirror.prototype.sourceLocation = function() {
   1329   var pos = this.sourcePosition_();
   1330   if (!IS_UNDEFINED(pos)) {
   1331     var script = this.func().script();
   1332     if (script) {
   1333       return script.locationFromPosition(pos, true);
   1334     }
   1335   }
   1336 };
   1337 
   1338 
   1339 GeneratorMirror.prototype.func = function() {
   1340   if (!this.func_) {
   1341     this.func_ = MakeMirror(%GeneratorGetFunction(this.value_));
   1342   }
   1343   return this.func_;
   1344 };
   1345 
   1346 
   1347 GeneratorMirror.prototype.receiver = function() {
   1348   if (!this.receiver_) {
   1349     this.receiver_ = MakeMirror(%GeneratorGetReceiver(this.value_));
   1350   }
   1351   return this.receiver_;
   1352 };
   1353 
   1354 
   1355 GeneratorMirror.prototype.scopeCount = function() {
   1356   // This value can change over time as the underlying generator is suspended
   1357   // at different locations.
   1358   return %GetGeneratorScopeCount(this.value());
   1359 };
   1360 
   1361 
   1362 GeneratorMirror.prototype.scope = function(index) {
   1363   return new ScopeMirror(UNDEFINED, UNDEFINED, this, index);
   1364 };
   1365 
   1366 
   1367 GeneratorMirror.prototype.allScopes = function() {
   1368   var scopes = [];
   1369   for (let i = 0; i < this.scopeCount(); i++) {
   1370     scopes.push(this.scope(i));
   1371   }
   1372   return scopes;
   1373 };
   1374 
   1375 
   1376 /**
   1377  * Base mirror object for properties.
   1378  * @param {ObjectMirror} mirror The mirror object having this property
   1379  * @param {string} name The name of the property
   1380  * @param {Array} details Details about the property
   1381  * @constructor
   1382  * @extends Mirror
   1383  */
   1384 function PropertyMirror(mirror, name, details) {
   1385   %_Call(Mirror, this, MirrorType.PROPERTY_TYPE);
   1386   this.mirror_ = mirror;
   1387   this.name_ = name;
   1388   this.value_ = details[0];
   1389   this.details_ = details[1];
   1390   this.is_interceptor_ = details[2];
   1391   if (details.length > 3) {
   1392     this.exception_ = details[3];
   1393     this.getter_ = details[4];
   1394     this.setter_ = details[5];
   1395   }
   1396 }
   1397 inherits(PropertyMirror, Mirror);
   1398 
   1399 
   1400 PropertyMirror.prototype.isReadOnly = function() {
   1401   return (this.attributes() & PropertyAttribute.ReadOnly) != 0;
   1402 };
   1403 
   1404 
   1405 PropertyMirror.prototype.isEnum = function() {
   1406   return (this.attributes() & PropertyAttribute.DontEnum) == 0;
   1407 };
   1408 
   1409 
   1410 PropertyMirror.prototype.canDelete = function() {
   1411   return (this.attributes() & PropertyAttribute.DontDelete) == 0;
   1412 };
   1413 
   1414 
   1415 PropertyMirror.prototype.name = function() {
   1416   return this.name_;
   1417 };
   1418 
   1419 
   1420 PropertyMirror.prototype.toText = function() {
   1421   if (IS_SYMBOL(this.name_)) return %SymbolDescriptiveString(this.name_);
   1422   return this.name_;
   1423 };
   1424 
   1425 
   1426 PropertyMirror.prototype.isIndexed = function() {
   1427   for (var i = 0; i < this.name_.length; i++) {
   1428     if (this.name_[i] < '0' || '9' < this.name_[i]) {
   1429       return false;
   1430     }
   1431   }
   1432   return true;
   1433 };
   1434 
   1435 
   1436 PropertyMirror.prototype.value = function() {
   1437   return MakeMirror(this.value_, false);
   1438 };
   1439 
   1440 
   1441 /**
   1442  * Returns whether this property value is an exception.
   1443  * @return {boolean} True if this property value is an exception
   1444  */
   1445 PropertyMirror.prototype.isException = function() {
   1446   return this.exception_ ? true : false;
   1447 };
   1448 
   1449 
   1450 PropertyMirror.prototype.attributes = function() {
   1451   return %DebugPropertyAttributesFromDetails(this.details_);
   1452 };
   1453 
   1454 
   1455 PropertyMirror.prototype.propertyType = function() {
   1456   return %DebugPropertyKindFromDetails(this.details_);
   1457 };
   1458 
   1459 
   1460 /**
   1461  * Returns whether this property has a getter defined through __defineGetter__.
   1462  * @return {boolean} True if this property has a getter
   1463  */
   1464 PropertyMirror.prototype.hasGetter = function() {
   1465   return this.getter_ ? true : false;
   1466 };
   1467 
   1468 
   1469 /**
   1470  * Returns whether this property has a setter defined through __defineSetter__.
   1471  * @return {boolean} True if this property has a setter
   1472  */
   1473 PropertyMirror.prototype.hasSetter = function() {
   1474   return this.setter_ ? true : false;
   1475 };
   1476 
   1477 
   1478 /**
   1479  * Returns the getter for this property defined through __defineGetter__.
   1480  * @return {Mirror} FunctionMirror reflecting the getter function or
   1481  *     UndefinedMirror if there is no getter for this property
   1482  */
   1483 PropertyMirror.prototype.getter = function() {
   1484   if (this.hasGetter()) {
   1485     return MakeMirror(this.getter_);
   1486   } else {
   1487     return GetUndefinedMirror();
   1488   }
   1489 };
   1490 
   1491 
   1492 /**
   1493  * Returns the setter for this property defined through __defineSetter__.
   1494  * @return {Mirror} FunctionMirror reflecting the setter function or
   1495  *     UndefinedMirror if there is no setter for this property
   1496  */
   1497 PropertyMirror.prototype.setter = function() {
   1498   if (this.hasSetter()) {
   1499     return MakeMirror(this.setter_);
   1500   } else {
   1501     return GetUndefinedMirror();
   1502   }
   1503 };
   1504 
   1505 
   1506 /**
   1507  * Returns whether this property is natively implemented by the host or a set
   1508  * through JavaScript code.
   1509  * @return {boolean} True if the property is
   1510  *     UndefinedMirror if there is no setter for this property
   1511  */
   1512 PropertyMirror.prototype.isNative = function() {
   1513   return this.is_interceptor_ ||
   1514          ((this.propertyType() == PropertyType.Accessor) &&
   1515           !this.hasGetter() && !this.hasSetter());
   1516 };
   1517 
   1518 
   1519 /**
   1520  * Mirror object for internal properties. Internal property reflects properties
   1521  * not accessible from user code such as [[BoundThis]] in bound function.
   1522  * Their names are merely symbolic.
   1523  * @param {string} name The name of the property
   1524  * @param {value} property value
   1525  * @constructor
   1526  * @extends Mirror
   1527  */
   1528 function InternalPropertyMirror(name, value) {
   1529   %_Call(Mirror, this, MirrorType.INTERNAL_PROPERTY_TYPE);
   1530   this.name_ = name;
   1531   this.value_ = value;
   1532 }
   1533 inherits(InternalPropertyMirror, Mirror);
   1534 
   1535 
   1536 InternalPropertyMirror.prototype.name = function() {
   1537   return this.name_;
   1538 };
   1539 
   1540 
   1541 InternalPropertyMirror.prototype.value = function() {
   1542   return MakeMirror(this.value_, false);
   1543 };
   1544 
   1545 
   1546 var kFrameDetailsFrameIdIndex = 0;
   1547 var kFrameDetailsReceiverIndex = 1;
   1548 var kFrameDetailsFunctionIndex = 2;
   1549 var kFrameDetailsScriptIndex = 3;
   1550 var kFrameDetailsArgumentCountIndex = 4;
   1551 var kFrameDetailsLocalCountIndex = 5;
   1552 var kFrameDetailsSourcePositionIndex = 6;
   1553 var kFrameDetailsConstructCallIndex = 7;
   1554 var kFrameDetailsAtReturnIndex = 8;
   1555 var kFrameDetailsFlagsIndex = 9;
   1556 var kFrameDetailsFirstDynamicIndex = 10;
   1557 
   1558 var kFrameDetailsNameIndex = 0;
   1559 var kFrameDetailsValueIndex = 1;
   1560 var kFrameDetailsNameValueSize = 2;
   1561 
   1562 var kFrameDetailsFlagDebuggerFrameMask = 1 << 0;
   1563 var kFrameDetailsFlagOptimizedFrameMask = 1 << 1;
   1564 var kFrameDetailsFlagInlinedFrameIndexMask = 7 << 2;
   1565 
   1566 /**
   1567  * Wrapper for the frame details information retreived from the VM. The frame
   1568  * details from the VM is an array with the following content. See runtime.cc
   1569  * Runtime_GetFrameDetails.
   1570  *     0: Id
   1571  *     1: Receiver
   1572  *     2: Function
   1573  *     3: Script
   1574  *     4: Argument count
   1575  *     5: Local count
   1576  *     6: Source position
   1577  *     7: Construct call
   1578  *     8: Is at return
   1579  *     9: Flags (debugger frame, optimized frame, inlined frame index)
   1580  *     Arguments name, value
   1581  *     Locals name, value
   1582  *     Return value if any
   1583  * @param {number} break_id Current break id
   1584  * @param {number} index Frame number
   1585  * @constructor
   1586  */
   1587 function FrameDetails(break_id, index) {
   1588   this.break_id_ = break_id;
   1589   this.details_ = %GetFrameDetails(break_id, index);
   1590 }
   1591 
   1592 
   1593 FrameDetails.prototype.frameId = function() {
   1594   %CheckExecutionState(this.break_id_);
   1595   return this.details_[kFrameDetailsFrameIdIndex];
   1596 };
   1597 
   1598 
   1599 FrameDetails.prototype.receiver = function() {
   1600   %CheckExecutionState(this.break_id_);
   1601   return this.details_[kFrameDetailsReceiverIndex];
   1602 };
   1603 
   1604 
   1605 FrameDetails.prototype.func = function() {
   1606   %CheckExecutionState(this.break_id_);
   1607   return this.details_[kFrameDetailsFunctionIndex];
   1608 };
   1609 
   1610 
   1611 FrameDetails.prototype.script = function() {
   1612   %CheckExecutionState(this.break_id_);
   1613   return this.details_[kFrameDetailsScriptIndex];
   1614 };
   1615 
   1616 
   1617 FrameDetails.prototype.isConstructCall = function() {
   1618   %CheckExecutionState(this.break_id_);
   1619   return this.details_[kFrameDetailsConstructCallIndex];
   1620 };
   1621 
   1622 
   1623 FrameDetails.prototype.isAtReturn = function() {
   1624   %CheckExecutionState(this.break_id_);
   1625   return this.details_[kFrameDetailsAtReturnIndex];
   1626 };
   1627 
   1628 
   1629 FrameDetails.prototype.isDebuggerFrame = function() {
   1630   %CheckExecutionState(this.break_id_);
   1631   var f = kFrameDetailsFlagDebuggerFrameMask;
   1632   return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
   1633 };
   1634 
   1635 
   1636 FrameDetails.prototype.isOptimizedFrame = function() {
   1637   %CheckExecutionState(this.break_id_);
   1638   var f = kFrameDetailsFlagOptimizedFrameMask;
   1639   return (this.details_[kFrameDetailsFlagsIndex] & f) == f;
   1640 };
   1641 
   1642 
   1643 FrameDetails.prototype.isInlinedFrame = function() {
   1644   return this.inlinedFrameIndex() > 0;
   1645 };
   1646 
   1647 
   1648 FrameDetails.prototype.inlinedFrameIndex = function() {
   1649   %CheckExecutionState(this.break_id_);
   1650   var f = kFrameDetailsFlagInlinedFrameIndexMask;
   1651   return (this.details_[kFrameDetailsFlagsIndex] & f) >> 2;
   1652 };
   1653 
   1654 
   1655 FrameDetails.prototype.argumentCount = function() {
   1656   %CheckExecutionState(this.break_id_);
   1657   return this.details_[kFrameDetailsArgumentCountIndex];
   1658 };
   1659 
   1660 
   1661 FrameDetails.prototype.argumentName = function(index) {
   1662   %CheckExecutionState(this.break_id_);
   1663   if (index >= 0 && index < this.argumentCount()) {
   1664     return this.details_[kFrameDetailsFirstDynamicIndex +
   1665                          index * kFrameDetailsNameValueSize +
   1666                          kFrameDetailsNameIndex];
   1667   }
   1668 };
   1669 
   1670 
   1671 FrameDetails.prototype.argumentValue = function(index) {
   1672   %CheckExecutionState(this.break_id_);
   1673   if (index >= 0 && index < this.argumentCount()) {
   1674     return this.details_[kFrameDetailsFirstDynamicIndex +
   1675                          index * kFrameDetailsNameValueSize +
   1676                          kFrameDetailsValueIndex];
   1677   }
   1678 };
   1679 
   1680 
   1681 FrameDetails.prototype.localCount = function() {
   1682   %CheckExecutionState(this.break_id_);
   1683   return this.details_[kFrameDetailsLocalCountIndex];
   1684 };
   1685 
   1686 
   1687 FrameDetails.prototype.sourcePosition = function() {
   1688   %CheckExecutionState(this.break_id_);
   1689   return this.details_[kFrameDetailsSourcePositionIndex];
   1690 };
   1691 
   1692 
   1693 FrameDetails.prototype.localName = function(index) {
   1694   %CheckExecutionState(this.break_id_);
   1695   if (index >= 0 && index < this.localCount()) {
   1696     var locals_offset = kFrameDetailsFirstDynamicIndex +
   1697                         this.argumentCount() * kFrameDetailsNameValueSize;
   1698     return this.details_[locals_offset +
   1699                          index * kFrameDetailsNameValueSize +
   1700                          kFrameDetailsNameIndex];
   1701   }
   1702 };
   1703 
   1704 
   1705 FrameDetails.prototype.localValue = function(index) {
   1706   %CheckExecutionState(this.break_id_);
   1707   if (index >= 0 && index < this.localCount()) {
   1708     var locals_offset = kFrameDetailsFirstDynamicIndex +
   1709                         this.argumentCount() * kFrameDetailsNameValueSize;
   1710     return this.details_[locals_offset +
   1711                          index * kFrameDetailsNameValueSize +
   1712                          kFrameDetailsValueIndex];
   1713   }
   1714 };
   1715 
   1716 
   1717 FrameDetails.prototype.returnValue = function() {
   1718   %CheckExecutionState(this.break_id_);
   1719   var return_value_offset =
   1720       kFrameDetailsFirstDynamicIndex +
   1721       (this.argumentCount() + this.localCount()) * kFrameDetailsNameValueSize;
   1722   if (this.details_[kFrameDetailsAtReturnIndex]) {
   1723     return this.details_[return_value_offset];
   1724   }
   1725 };
   1726 
   1727 
   1728 FrameDetails.prototype.scopeCount = function() {
   1729   if (IS_UNDEFINED(this.scopeCount_)) {
   1730     this.scopeCount_ = %GetScopeCount(this.break_id_, this.frameId());
   1731   }
   1732   return this.scopeCount_;
   1733 };
   1734 
   1735 
   1736 /**
   1737  * Mirror object for stack frames.
   1738  * @param {number} break_id The break id in the VM for which this frame is
   1739        valid
   1740  * @param {number} index The frame index (top frame is index 0)
   1741  * @constructor
   1742  * @extends Mirror
   1743  */
   1744 function FrameMirror(break_id, index) {
   1745   %_Call(Mirror, this, MirrorType.FRAME_TYPE);
   1746   this.break_id_ = break_id;
   1747   this.index_ = index;
   1748   this.details_ = new FrameDetails(break_id, index);
   1749 }
   1750 inherits(FrameMirror, Mirror);
   1751 
   1752 
   1753 FrameMirror.prototype.details = function() {
   1754   return this.details_;
   1755 };
   1756 
   1757 
   1758 FrameMirror.prototype.index = function() {
   1759   return this.index_;
   1760 };
   1761 
   1762 
   1763 FrameMirror.prototype.func = function() {
   1764   if (this.func_) {
   1765     return this.func_;
   1766   }
   1767 
   1768   // Get the function for this frame from the VM.
   1769   var f = this.details_.func();
   1770 
   1771   // Create a function mirror. NOTE: MakeMirror cannot be used here as the
   1772   // value returned from the VM might be a string if the function for the
   1773   // frame is unresolved.
   1774   if (IS_FUNCTION(f)) {
   1775     return this.func_ = MakeMirror(f);
   1776   } else {
   1777     return new UnresolvedFunctionMirror(f);
   1778   }
   1779 };
   1780 
   1781 
   1782 FrameMirror.prototype.script = function() {
   1783   if (!this.script_) {
   1784     this.script_ = MakeMirror(this.details_.script());
   1785   }
   1786 
   1787   return this.script_;
   1788 }
   1789 
   1790 
   1791 FrameMirror.prototype.receiver = function() {
   1792   return MakeMirror(this.details_.receiver());
   1793 };
   1794 
   1795 
   1796 FrameMirror.prototype.isConstructCall = function() {
   1797   return this.details_.isConstructCall();
   1798 };
   1799 
   1800 
   1801 FrameMirror.prototype.isAtReturn = function() {
   1802   return this.details_.isAtReturn();
   1803 };
   1804 
   1805 
   1806 FrameMirror.prototype.isDebuggerFrame = function() {
   1807   return this.details_.isDebuggerFrame();
   1808 };
   1809 
   1810 
   1811 FrameMirror.prototype.isOptimizedFrame = function() {
   1812   return this.details_.isOptimizedFrame();
   1813 };
   1814 
   1815 
   1816 FrameMirror.prototype.isInlinedFrame = function() {
   1817   return this.details_.isInlinedFrame();
   1818 };
   1819 
   1820 
   1821 FrameMirror.prototype.inlinedFrameIndex = function() {
   1822   return this.details_.inlinedFrameIndex();
   1823 };
   1824 
   1825 
   1826 FrameMirror.prototype.argumentCount = function() {
   1827   return this.details_.argumentCount();
   1828 };
   1829 
   1830 
   1831 FrameMirror.prototype.argumentName = function(index) {
   1832   return this.details_.argumentName(index);
   1833 };
   1834 
   1835 
   1836 FrameMirror.prototype.argumentValue = function(index) {
   1837   return MakeMirror(this.details_.argumentValue(index));
   1838 };
   1839 
   1840 
   1841 FrameMirror.prototype.localCount = function() {
   1842   return this.details_.localCount();
   1843 };
   1844 
   1845 
   1846 FrameMirror.prototype.localName = function(index) {
   1847   return this.details_.localName(index);
   1848 };
   1849 
   1850 
   1851 FrameMirror.prototype.localValue = function(index) {
   1852   return MakeMirror(this.details_.localValue(index));
   1853 };
   1854 
   1855 
   1856 FrameMirror.prototype.returnValue = function() {
   1857   return MakeMirror(this.details_.returnValue());
   1858 };
   1859 
   1860 
   1861 FrameMirror.prototype.sourcePosition = function() {
   1862   return this.details_.sourcePosition();
   1863 };
   1864 
   1865 
   1866 FrameMirror.prototype.sourceLocation = function() {
   1867   var script = this.script();
   1868   if (script) {
   1869     return script.locationFromPosition(this.sourcePosition(), true);
   1870   }
   1871 };
   1872 
   1873 
   1874 FrameMirror.prototype.sourceLine = function() {
   1875   var location = this.sourceLocation();
   1876   if (location) {
   1877     return location.line;
   1878   }
   1879 };
   1880 
   1881 
   1882 FrameMirror.prototype.sourceColumn = function() {
   1883   var location = this.sourceLocation();
   1884   if (location) {
   1885     return location.column;
   1886   }
   1887 };
   1888 
   1889 
   1890 FrameMirror.prototype.sourceLineText = function() {
   1891   var location = this.sourceLocation();
   1892   if (location) {
   1893     return location.sourceText;
   1894   }
   1895 };
   1896 
   1897 
   1898 FrameMirror.prototype.scopeCount = function() {
   1899   return this.details_.scopeCount();
   1900 };
   1901 
   1902 
   1903 FrameMirror.prototype.scope = function(index) {
   1904   return new ScopeMirror(this, UNDEFINED, UNDEFINED, index);
   1905 };
   1906 
   1907 
   1908 FrameMirror.prototype.allScopes = function(opt_ignore_nested_scopes) {
   1909   var scopeDetails = %GetAllScopesDetails(this.break_id_,
   1910                                           this.details_.frameId(),
   1911                                           this.details_.inlinedFrameIndex(),
   1912                                           !!opt_ignore_nested_scopes);
   1913   var result = [];
   1914   for (var i = 0; i < scopeDetails.length; ++i) {
   1915     result.push(new ScopeMirror(this, UNDEFINED, UNDEFINED, i,
   1916                                 scopeDetails[i]));
   1917   }
   1918   return result;
   1919 };
   1920 
   1921 
   1922 FrameMirror.prototype.evaluate = function(source, throw_on_side_effect = false) {
   1923   return MakeMirror(%DebugEvaluate(this.break_id_,
   1924                                    this.details_.frameId(),
   1925                                    this.details_.inlinedFrameIndex(),
   1926                                    source,
   1927                                    throw_on_side_effect));
   1928 };
   1929 
   1930 
   1931 FrameMirror.prototype.invocationText = function() {
   1932   // Format frame invoaction (receiver, function and arguments).
   1933   var result = '';
   1934   var func = this.func();
   1935   var receiver = this.receiver();
   1936   if (this.isConstructCall()) {
   1937     // For constructor frames display new followed by the function name.
   1938     result += 'new ';
   1939     result += func.name() ? func.name() : '[anonymous]';
   1940   } else if (this.isDebuggerFrame()) {
   1941     result += '[debugger]';
   1942   } else {
   1943     // If the receiver has a className which is 'global' don't display it.
   1944     var display_receiver =
   1945       !receiver.className || (receiver.className() != 'global');
   1946     if (display_receiver) {
   1947       result += receiver.toText();
   1948     }
   1949     // Try to find the function as a property in the receiver. Include the
   1950     // prototype chain in the lookup.
   1951     var property = GetUndefinedMirror();
   1952     if (receiver.isObject()) {
   1953       for (var r = receiver;
   1954            !r.isNull() && property.isUndefined();
   1955            r = r.protoObject()) {
   1956         property = r.lookupProperty(func);
   1957       }
   1958     }
   1959     if (!property.isUndefined()) {
   1960       // The function invoked was found on the receiver. Use the property name
   1961       // for the backtrace.
   1962       if (!property.isIndexed()) {
   1963         if (display_receiver) {
   1964           result += '.';
   1965         }
   1966         result += property.toText();
   1967       } else {
   1968         result += '[';
   1969         result += property.toText();
   1970         result += ']';
   1971       }
   1972       // Also known as - if the name in the function doesn't match the name
   1973       // under which it was looked up.
   1974       if (func.name() && func.name() != property.name()) {
   1975         result += '(aka ' + func.name() + ')';
   1976       }
   1977     } else {
   1978       // The function invoked was not found on the receiver. Use the function
   1979       // name if available for the backtrace.
   1980       if (display_receiver) {
   1981         result += '.';
   1982       }
   1983       result += func.name() ? func.name() : '[anonymous]';
   1984     }
   1985   }
   1986 
   1987   // Render arguments for normal frames.
   1988   if (!this.isDebuggerFrame()) {
   1989     result += '(';
   1990     for (var i = 0; i < this.argumentCount(); i++) {
   1991       if (i != 0) result += ', ';
   1992       if (this.argumentName(i)) {
   1993         result += this.argumentName(i);
   1994         result += '=';
   1995       }
   1996       result += this.argumentValue(i).toText();
   1997     }
   1998     result += ')';
   1999   }
   2000 
   2001   if (this.isAtReturn()) {
   2002     result += ' returning ';
   2003     result += this.returnValue().toText();
   2004   }
   2005 
   2006   return result;
   2007 };
   2008 
   2009 
   2010 FrameMirror.prototype.sourceAndPositionText = function() {
   2011   // Format source and position.
   2012   var result = '';
   2013   var func = this.func();
   2014   if (func.resolved()) {
   2015     var script = func.script();
   2016     if (script) {
   2017       if (script.name()) {
   2018         result += script.name();
   2019       } else {
   2020         result += '[unnamed]';
   2021       }
   2022       if (!this.isDebuggerFrame()) {
   2023         var location = this.sourceLocation();
   2024         result += ' line ';
   2025         result += !IS_UNDEFINED(location) ? (location.line + 1) : '?';
   2026         result += ' column ';
   2027         result += !IS_UNDEFINED(location) ? (location.column + 1) : '?';
   2028         if (!IS_UNDEFINED(this.sourcePosition())) {
   2029           result += ' (position ' + (this.sourcePosition() + 1) + ')';
   2030         }
   2031       }
   2032     } else {
   2033       result += '[no source]';
   2034     }
   2035   } else {
   2036     result += '[unresolved]';
   2037   }
   2038 
   2039   return result;
   2040 };
   2041 
   2042 
   2043 FrameMirror.prototype.localsText = function() {
   2044   // Format local variables.
   2045   var result = '';
   2046   var locals_count = this.localCount();
   2047   if (locals_count > 0) {
   2048     for (var i = 0; i < locals_count; ++i) {
   2049       result += '      var ';
   2050       result += this.localName(i);
   2051       result += ' = ';
   2052       result += this.localValue(i).toText();
   2053       if (i < locals_count - 1) result += '\n';
   2054     }
   2055   }
   2056 
   2057   return result;
   2058 };
   2059 
   2060 
   2061 FrameMirror.prototype.restart = function() {
   2062   var result = %LiveEditRestartFrame(this.break_id_, this.index_);
   2063   if (IS_UNDEFINED(result)) {
   2064     result = "Failed to find requested frame";
   2065   }
   2066   return result;
   2067 };
   2068 
   2069 
   2070 FrameMirror.prototype.toText = function(opt_locals) {
   2071   var result = '';
   2072   result += '#' + (this.index() <= 9 ? '0' : '') + this.index();
   2073   result += ' ';
   2074   result += this.invocationText();
   2075   result += ' ';
   2076   result += this.sourceAndPositionText();
   2077   if (opt_locals) {
   2078     result += '\n';
   2079     result += this.localsText();
   2080   }
   2081   return result;
   2082 };
   2083 
   2084 
   2085 // This indexes correspond definitions in debug-scopes.h.
   2086 var kScopeDetailsTypeIndex = 0;
   2087 var kScopeDetailsObjectIndex = 1;
   2088 var kScopeDetailsNameIndex = 2;
   2089 var kScopeDetailsStartPositionIndex = 3;
   2090 var kScopeDetailsEndPositionIndex = 4;
   2091 var kScopeDetailsFunctionIndex = 5;
   2092 
   2093 function ScopeDetails(frame, fun, gen, index, opt_details) {
   2094   if (frame) {
   2095     this.break_id_ = frame.break_id_;
   2096     this.details_ = opt_details ||
   2097                     %GetScopeDetails(frame.break_id_,
   2098                                      frame.details_.frameId(),
   2099                                      frame.details_.inlinedFrameIndex(),
   2100                                      index);
   2101     this.frame_id_ = frame.details_.frameId();
   2102     this.inlined_frame_id_ = frame.details_.inlinedFrameIndex();
   2103   } else if (fun) {
   2104     this.details_ = opt_details || %GetFunctionScopeDetails(fun.value(), index);
   2105     this.fun_value_ = fun.value();
   2106     this.break_id_ = UNDEFINED;
   2107   } else {
   2108     this.details_ =
   2109       opt_details || %GetGeneratorScopeDetails(gen.value(), index);
   2110     this.gen_value_ = gen.value();
   2111     this.break_id_ = UNDEFINED;
   2112   }
   2113   this.index_ = index;
   2114 }
   2115 
   2116 
   2117 ScopeDetails.prototype.type = function() {
   2118   if (!IS_UNDEFINED(this.break_id_)) {
   2119     %CheckExecutionState(this.break_id_);
   2120   }
   2121   return this.details_[kScopeDetailsTypeIndex];
   2122 };
   2123 
   2124 
   2125 ScopeDetails.prototype.object = function() {
   2126   if (!IS_UNDEFINED(this.break_id_)) {
   2127     %CheckExecutionState(this.break_id_);
   2128   }
   2129   return this.details_[kScopeDetailsObjectIndex];
   2130 };
   2131 
   2132 
   2133 ScopeDetails.prototype.name = function() {
   2134   if (!IS_UNDEFINED(this.break_id_)) {
   2135     %CheckExecutionState(this.break_id_);
   2136   }
   2137   return this.details_[kScopeDetailsNameIndex];
   2138 };
   2139 
   2140 
   2141 ScopeDetails.prototype.startPosition = function() {
   2142   if (!IS_UNDEFINED(this.break_id_)) {
   2143     %CheckExecutionState(this.break_id_);
   2144   }
   2145   return this.details_[kScopeDetailsStartPositionIndex];
   2146 }
   2147 
   2148 
   2149 ScopeDetails.prototype.endPosition = function() {
   2150   if (!IS_UNDEFINED(this.break_id_)) {
   2151     %CheckExecutionState(this.break_id_);
   2152   }
   2153   return this.details_[kScopeDetailsEndPositionIndex];
   2154 }
   2155 
   2156 ScopeDetails.prototype.func = function() {
   2157   if (!IS_UNDEFINED(this.break_id_)) {
   2158     %CheckExecutionState(this.break_id_);
   2159   }
   2160   return this.details_[kScopeDetailsFunctionIndex];
   2161 }
   2162 
   2163 
   2164 ScopeDetails.prototype.setVariableValueImpl = function(name, new_value) {
   2165   var raw_res;
   2166   if (!IS_UNDEFINED(this.break_id_)) {
   2167     %CheckExecutionState(this.break_id_);
   2168     raw_res = %SetScopeVariableValue(this.break_id_, this.frame_id_,
   2169         this.inlined_frame_id_, this.index_, name, new_value);
   2170   } else if (!IS_UNDEFINED(this.fun_value_)) {
   2171     raw_res = %SetScopeVariableValue(this.fun_value_, null, null, this.index_,
   2172         name, new_value);
   2173   } else {
   2174     raw_res = %SetScopeVariableValue(this.gen_value_, null, null, this.index_,
   2175         name, new_value);
   2176   }
   2177   if (!raw_res) throw %make_error(kDebugger, "Failed to set variable value");
   2178 };
   2179 
   2180 
   2181 /**
   2182  * Mirror object for scope of frame or function. Either frame or function must
   2183  * be specified.
   2184  * @param {FrameMirror} frame The frame this scope is a part of
   2185  * @param {FunctionMirror} function The function this scope is a part of
   2186  * @param {GeneratorMirror} gen The generator this scope is a part of
   2187  * @param {number} index The scope index in the frame
   2188  * @param {Array=} opt_details Raw scope details data
   2189  * @constructor
   2190  * @extends Mirror
   2191  */
   2192 function ScopeMirror(frame, fun, gen, index, opt_details) {
   2193   %_Call(Mirror, this, MirrorType.SCOPE_TYPE);
   2194   if (frame) {
   2195     this.frame_index_ = frame.index_;
   2196   } else {
   2197     this.frame_index_ = UNDEFINED;
   2198   }
   2199   this.scope_index_ = index;
   2200   this.details_ = new ScopeDetails(frame, fun, gen, index, opt_details);
   2201 }
   2202 inherits(ScopeMirror, Mirror);
   2203 
   2204 
   2205 ScopeMirror.prototype.details = function() {
   2206   return this.details_;
   2207 };
   2208 
   2209 
   2210 ScopeMirror.prototype.frameIndex = function() {
   2211   return this.frame_index_;
   2212 };
   2213 
   2214 
   2215 ScopeMirror.prototype.scopeIndex = function() {
   2216   return this.scope_index_;
   2217 };
   2218 
   2219 
   2220 ScopeMirror.prototype.scopeType = function() {
   2221   return this.details_.type();
   2222 };
   2223 
   2224 
   2225 ScopeMirror.prototype.scopeObject = function() {
   2226   // For local, closure and script scopes create a mirror
   2227   // as these objects are created on the fly materializing the local
   2228   // or closure scopes and therefore will not preserve identity.
   2229   return MakeMirror(this.details_.object());
   2230 };
   2231 
   2232 
   2233 ScopeMirror.prototype.setVariableValue = function(name, new_value) {
   2234   this.details_.setVariableValueImpl(name, new_value);
   2235 };
   2236 
   2237 
   2238 /**
   2239  * Mirror object for script source.
   2240  * @param {Script} script The script object
   2241  * @constructor
   2242  * @extends Mirror
   2243  */
   2244 function ScriptMirror(script) {
   2245   %_Call(Mirror, this, MirrorType.SCRIPT_TYPE);
   2246   this.script_ = script;
   2247   this.context_ = new ContextMirror(script.context_data);
   2248 }
   2249 inherits(ScriptMirror, Mirror);
   2250 
   2251 
   2252 ScriptMirror.prototype.value = function() {
   2253   return this.script_;
   2254 };
   2255 
   2256 
   2257 ScriptMirror.prototype.name = function() {
   2258   return this.script_.name || this.script_.nameOrSourceURL();
   2259 };
   2260 
   2261 
   2262 ScriptMirror.prototype.id = function() {
   2263   return this.script_.id;
   2264 };
   2265 
   2266 
   2267 ScriptMirror.prototype.source = function() {
   2268   return this.script_.source;
   2269 };
   2270 
   2271 
   2272 ScriptMirror.prototype.setSource = function(source) {
   2273   if (!IS_STRING(source)) throw %make_error(kDebugger, "Source is not a string");
   2274   %DebugSetScriptSource(this.script_, source);
   2275 };
   2276 
   2277 
   2278 ScriptMirror.prototype.lineOffset = function() {
   2279   return this.script_.line_offset;
   2280 };
   2281 
   2282 
   2283 ScriptMirror.prototype.columnOffset = function() {
   2284   return this.script_.column_offset;
   2285 };
   2286 
   2287 
   2288 ScriptMirror.prototype.data = function() {
   2289   return this.script_.data;
   2290 };
   2291 
   2292 
   2293 ScriptMirror.prototype.scriptType = function() {
   2294   return this.script_.type;
   2295 };
   2296 
   2297 
   2298 ScriptMirror.prototype.compilationType = function() {
   2299   return this.script_.compilation_type;
   2300 };
   2301 
   2302 
   2303 ScriptMirror.prototype.lineCount = function() {
   2304   return %ScriptLineCount(this.script_);
   2305 };
   2306 
   2307 
   2308 ScriptMirror.prototype.locationFromPosition = function(
   2309     position, include_resource_offset) {
   2310   return this.script_.locationFromPosition(position, include_resource_offset);
   2311 };
   2312 
   2313 
   2314 ScriptMirror.prototype.context = function() {
   2315   return this.context_;
   2316 };
   2317 
   2318 
   2319 ScriptMirror.prototype.evalFromScript = function() {
   2320   return MakeMirror(this.script_.eval_from_script);
   2321 };
   2322 
   2323 
   2324 ScriptMirror.prototype.evalFromFunctionName = function() {
   2325   return MakeMirror(this.script_.eval_from_function_name);
   2326 };
   2327 
   2328 
   2329 ScriptMirror.prototype.evalFromLocation = function() {
   2330   var eval_from_script = this.evalFromScript();
   2331   if (!eval_from_script.isUndefined()) {
   2332     var position = this.script_.eval_from_script_position;
   2333     return eval_from_script.locationFromPosition(position, true);
   2334   }
   2335 };
   2336 
   2337 
   2338 ScriptMirror.prototype.toText = function() {
   2339   var result = '';
   2340   result += this.name();
   2341   result += ' (lines: ';
   2342   if (this.lineOffset() > 0) {
   2343     result += this.lineOffset();
   2344     result += '-';
   2345     result += this.lineOffset() + this.lineCount() - 1;
   2346   } else {
   2347     result += this.lineCount();
   2348   }
   2349   result += ')';
   2350   return result;
   2351 };
   2352 
   2353 
   2354 /**
   2355  * Mirror object for context.
   2356  * @param {Object} data The context data
   2357  * @constructor
   2358  * @extends Mirror
   2359  */
   2360 function ContextMirror(data) {
   2361   %_Call(Mirror, this, MirrorType.CONTEXT_TYPE);
   2362   this.data_ = data;
   2363 }
   2364 inherits(ContextMirror, Mirror);
   2365 
   2366 
   2367 ContextMirror.prototype.data = function() {
   2368   return this.data_;
   2369 };
   2370 
   2371 // ----------------------------------------------------------------------------
   2372 // Exports
   2373 
   2374 utils.InstallFunctions(global, DONT_ENUM, [
   2375   "MakeMirror", MakeMirror,
   2376 ]);
   2377 
   2378 utils.InstallConstants(global, [
   2379   "ScopeType", ScopeType,
   2380   "PropertyType", PropertyType,
   2381   "PropertyAttribute", PropertyAttribute,
   2382   "Mirror", Mirror,
   2383   "ValueMirror", ValueMirror,
   2384   "UndefinedMirror", UndefinedMirror,
   2385   "NullMirror", NullMirror,
   2386   "BooleanMirror", BooleanMirror,
   2387   "NumberMirror", NumberMirror,
   2388   "StringMirror", StringMirror,
   2389   "SymbolMirror", SymbolMirror,
   2390   "ObjectMirror", ObjectMirror,
   2391   "FunctionMirror", FunctionMirror,
   2392   "UnresolvedFunctionMirror", UnresolvedFunctionMirror,
   2393   "ArrayMirror", ArrayMirror,
   2394   "DateMirror", DateMirror,
   2395   "RegExpMirror", RegExpMirror,
   2396   "ErrorMirror", ErrorMirror,
   2397   "PromiseMirror", PromiseMirror,
   2398   "MapMirror", MapMirror,
   2399   "SetMirror", SetMirror,
   2400   "IteratorMirror", IteratorMirror,
   2401   "GeneratorMirror", GeneratorMirror,
   2402   "PropertyMirror", PropertyMirror,
   2403   "InternalPropertyMirror", InternalPropertyMirror,
   2404   "FrameMirror", FrameMirror,
   2405   "ScriptMirror", ScriptMirror,
   2406   "ScopeMirror", ScopeMirror,
   2407   "FrameDetails", FrameDetails,
   2408 ]);
   2409 
   2410 })
   2411