Chromium Code Reviews| Index: src/mirror-debugger.js |
| diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js |
| index 94e616a7f53028e415bb3291ea2d13f77eca8092..2e6b551471be71a2a32a357dcbbd548f5572fce3 100644 |
| --- a/src/mirror-debugger.js |
| +++ b/src/mirror-debugger.js |
| @@ -154,6 +154,7 @@ var FUNCTION_TYPE = 'function'; |
| var REGEXP_TYPE = 'regexp'; |
| var ERROR_TYPE = 'error'; |
| var PROPERTY_TYPE = 'property'; |
| +var INTERNAL_PROPERTY_TYPE = 'internalProperty'; |
| var FRAME_TYPE = 'frame'; |
| var SCRIPT_TYPE = 'script'; |
| var CONTEXT_TYPE = 'context'; |
| @@ -212,6 +213,7 @@ var ScopeType = { Global: 0, |
| // - RegExpMirror |
| // - ErrorMirror |
| // - PropertyMirror |
| +// - InternalPropertyMirror |
| // - FrameMirror |
| // - ScriptMirror |
| @@ -358,6 +360,15 @@ Mirror.prototype.isProperty = function() { |
| /** |
| + * Check whether the mirror reflects an internal property. |
| + * @returns {boolean} True if the mirror reflects an internal property |
| + */ |
| +Mirror.prototype.isInternalProperty = function() { |
| + return this instanceof InternalPropertyMirror; |
| +}; |
| + |
| + |
| +/** |
| * Check whether the mirror reflects a stack frame. |
| * @returns {boolean} True if the mirror reflects a stack frame |
| */ |
| @@ -594,23 +605,6 @@ ObjectMirror.prototype.protoObject = function() { |
| }; |
| -/** |
| - * Return the primitive value if this is object of Boolean, Number or String |
| - * type (but not Date). Otherwise return undefined. |
| - */ |
| -ObjectMirror.prototype.primitiveValue = function() { |
| - if (!IS_STRING_WRAPPER(this.value_) && !IS_NUMBER_WRAPPER(this.value_) && |
| - !IS_BOOLEAN_WRAPPER(this.value_)) { |
| - return void 0; |
| - } |
| - var primitiveValue = %_ValueOf(this.value_); |
| - if (IS_UNDEFINED(primitiveValue)) { |
| - return void 0; |
| - } |
| - return MakeMirror(primitiveValue); |
| -}; |
| - |
| - |
| ObjectMirror.prototype.hasNamedInterceptor = function() { |
| // Get information on interceptors for this object. |
| var x = %GetInterceptorInfo(this.value_); |
| @@ -701,7 +695,7 @@ ObjectMirror.prototype.propertyNames = function(kind, limit) { |
| * Return the properties for this object as an array of PropertyMirror objects. |
| * @param {number} kind Indicate whether named, indexed or both kinds of |
| * properties are requested |
| - * @param {number} limit Limit the number of properties returend to the |
| + * @param {number} limit Limit the number of properties returned to the |
| specified value |
| * @return {Array} Property mirrors for this object |
| */ |
| @@ -716,6 +710,16 @@ ObjectMirror.prototype.properties = function(kind, limit) { |
| }; |
| +/** |
| + * Return the internal properties for this object as an array of |
| + * InternalPropertyMirror objects. |
| + * @return {Array} Property mirrors for this object |
| + */ |
| +ObjectMirror.prototype.internalProperties = function() { |
| + return ObjectMirror.GetInternalProperties(this.value_); |
| +} |
| + |
| + |
| ObjectMirror.prototype.property = function(name) { |
| var details = %DebugGetPropertyDetails(this.value_, %ToString(name)); |
| if (details) { |
| @@ -790,6 +794,37 @@ ObjectMirror.prototype.toText = function() { |
| /** |
| + * Return the internal properties of the value, such as [[PrimitiveValue]] of |
| + * scalar wrapper objects and properties of the bound function. |
| + * This method is done static to be accessible from Debug API with the bare |
| + * values without mirrors. |
| + * @return {Array} array (possibly empty) of InternalProperty instances |
| + */ |
| +ObjectMirror.GetInternalProperties = function(value) { |
| + if (IS_STRING_WRAPPER(value) || IS_NUMBER_WRAPPER(value) || |
| + IS_BOOLEAN_WRAPPER(value)) { |
| + var primitiveValue = %_ValueOf(value); |
| + return [new InternalPropertyMirror("[[PrimitiveValue]]", primitiveValue)]; |
| + } else if (IS_FUNCTION(value)) { |
| + var bindings = %BoundFunctionGetBindings(value); |
| + var result = []; |
| + if (bindings && IS_ARRAY(bindings)) { |
| + result.push(new InternalPropertyMirror("[[TargetFunction]]", |
| + bindings[0])); |
| + result.push(new InternalPropertyMirror("[[BoundThis]]", bindings[1])); |
| + var boundArgs = []; |
| + for (var i = 2; i < bindings.length; i++) { |
| + boundArgs.push(bindings[i]); |
| + } |
| + result.push(new InternalPropertyMirror("[[BoundArgs]]", boundArgs)); |
| + } |
| + return result; |
| + } |
| + return []; |
| +} |
| + |
| + |
| +/** |
| * Mirror object for functions. |
| * @param {function} value The function object reflected by this mirror. |
| * @constructor |
| @@ -1268,6 +1303,33 @@ PropertyMirror.prototype.isNative = function() { |
| }; |
| +/** |
| + * Mirror object for internal properties. Internal property reflects properties |
| + * not accessible from user code such as [[BoundThis]] in bound function. |
| + * Their names are merely symbolic. |
| + * @param {string} name The name of the property |
| + * @param {value} property value |
| + * @constructor |
| + * @extends Mirror |
| + */ |
| +function InternalPropertyMirror(name, value) { |
| + %_CallFunction(this, INTERNAL_PROPERTY_TYPE, Mirror); |
| + this.name_ = name; |
| + this.value_ = value; |
| +} |
| +inherits(InternalPropertyMirror, Mirror); |
| + |
| + |
| +InternalPropertyMirror.prototype.name = function() { |
| + return this.name_; |
| +}; |
| + |
| + |
| +InternalPropertyMirror.prototype.value = function() { |
| + return MakeMirror(this.value_, false); |
| +}; |
| + |
| + |
| var kFrameDetailsFrameIdIndex = 0; |
| var kFrameDetailsReceiverIndex = 1; |
| var kFrameDetailsFunctionIndex = 2; |
| @@ -2202,6 +2264,7 @@ JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference, |
| break; |
| case PROPERTY_TYPE: |
| + case INTERNAL_PROPERTY_TYPE: |
| throw new Error('PropertyMirror cannot be serialized independeltly'); |
|
Yang
2012/08/17 11:20:44
"independently"
Peter Rybin
2012/08/17 23:13:09
Done.
|
| break; |
| @@ -2289,11 +2352,6 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content, |
| content.protoObject = this.serializeReference(mirror.protoObject()); |
| content.prototypeObject = this.serializeReference(mirror.prototypeObject()); |
| - var primitiveValue = mirror.primitiveValue(); |
| - if (!IS_UNDEFINED(primitiveValue)) { |
| - content.primitiveValue = this.serializeReference(primitiveValue); |
| - } |
| - |
| // Add flags to indicate whether there are interceptors. |
| if (mirror.hasNamedInterceptor()) { |
| content.namedInterceptor = true; |
| @@ -2355,6 +2413,15 @@ JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content, |
| } |
| } |
| content.properties = p; |
| + |
| + var internalProperties = mirror.internalProperties(); |
| + if (internalProperties.length > 0) { |
| + var ip = []; |
| + for (var i = 0; i < internalProperties.length; i++) { |
| + ip.push(this.serializeInternalProperty_(internalProperties[i])); |
| + } |
| + content.internalProperties = ip; |
| + } |
| }; |
| @@ -2422,6 +2489,33 @@ JSONProtocolSerializer.prototype.serializeProperty_ = function(propertyMirror) { |
| }; |
| +/** |
| + * Serialize internal property information to the following JSON format for |
| + * building the array of properties. |
| + * |
| + * {"name":"<property name>", |
| + * "ref":<number>} |
| + * |
| + * {"name":"[[BoundThis]]","ref":117} |
| + * |
| + * @param {InternalPropertyMirror} propertyMirror The property to serialize. |
| + * @returns {Object} Protocol object representing the property. |
| + */ |
| +JSONProtocolSerializer.prototype.serializeInternalProperty_ = |
| + function(propertyMirror) { |
| + var result = {}; |
| + |
| + result.name = propertyMirror.name(); |
| + var propertyValue = propertyMirror.value(); |
| + if (this.inlineRefs_() && propertyValue.isValue()) { |
| + result.value = this.serializeReferenceWithDisplayData_(propertyValue); |
| + } else { |
| + result.ref = propertyValue.handle(); |
| + } |
| + return result; |
| +}; |
| + |
| + |
| JSONProtocolSerializer.prototype.serializeFrame_ = function(mirror, content) { |
| content.index = mirror.index(); |
| content.receiver = this.serializeReference(mirror.receiver()); |