Index: src/mirror-debugger.js |
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js |
index 94e616a7f53028e415bb3291ea2d13f77eca8092..a5331a014de6f79f30404dd19a5965a5a7969769 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,7 +2264,8 @@ JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference, |
break; |
case PROPERTY_TYPE: |
- throw new Error('PropertyMirror cannot be serialized independeltly'); |
+ case INTERNAL_PROPERTY_TYPE: |
+ throw new Error('PropertyMirror cannot be serialized independently'); |
break; |
case FRAME_TYPE: |
@@ -2278,7 +2341,8 @@ JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference, |
* "prototypeObject":{"ref":<number>}, |
* "namedInterceptor":<boolean>, |
* "indexedInterceptor":<boolean>, |
- * "properties":[<properties>]} |
+ * "properties":[<properties>], |
+ * "internalProperties":[<internal properties>]} |
*/ |
JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content, |
details) { |
@@ -2289,11 +2353,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 +2414,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 +2490,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()); |