Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Unified Diff: src/mirror-delay.js

Issue 18092: Added handles to the mirror objects. When a mirror for an object is created... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/debug-delay.js ('k') | test/mjsunit/debug-backtrace.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mirror-delay.js
===================================================================
--- src/mirror-delay.js (revision 1079)
+++ src/mirror-delay.js (working copy)
@@ -33,28 +33,73 @@
Date;
+var next_handle_ = 0;
+var mirror_cache_ = [];
+
/**
+ * Clear the mirror handle cache.
+ */
+function ClearMirrorCache() {
+ next_handle_ = 0;
+ mirror_cache_ = [];
+}
+
+
+/**
* Returns the mirror for a specified value or object.
*
* @param {value or Object} value the value or object to retreive the mirror for
* @returns {Mirror} the mirror reflects the passed value or object
*/
function MakeMirror(value) {
- if (IS_UNDEFINED(value)) return new UndefinedMirror();
- if (IS_NULL(value)) return new NullMirror();
- if (IS_BOOLEAN(value)) return new BooleanMirror(value);
- if (IS_NUMBER(value)) return new NumberMirror(value);
- if (IS_STRING(value)) return new StringMirror(value);
- if (IS_ARRAY(value)) return new ArrayMirror(value);
- if (IS_DATE(value)) return new DateMirror(value);
- if (IS_FUNCTION(value)) return new FunctionMirror(value);
- if (IS_REGEXP(value)) return new RegExpMirror(value);
- if (IS_ERROR(value)) return new ErrorMirror(value);
- return new ObjectMirror(value);
+ var mirror;
+ for (id in mirror_cache_) {
+ mirror = mirror_cache_[id];
+ if (mirror.value() === value) {
+ return mirror;
+ }
+ }
+
+ if (IS_UNDEFINED(value)) {
+ mirror = new UndefinedMirror();
+ } else if (IS_NULL(value)) {
+ mirror = new NullMirror();
+ } else if (IS_BOOLEAN(value)) {
+ mirror = new BooleanMirror(value);
+ } else if (IS_NUMBER(value)) {
+ mirror = new NumberMirror(value);
+ } else if (IS_STRING(value)) {
+ mirror = new StringMirror(value);
+ } else if (IS_ARRAY(value)) {
+ mirror = new ArrayMirror(value);
+ } else if (IS_DATE(value)) {
+ mirror = new DateMirror(value);
+ } else if (IS_FUNCTION(value)) {
+ mirror = new FunctionMirror(value);
+ } else if (IS_REGEXP(value)) {
+ mirror = new RegExpMirror(value);
+ } else if (IS_ERROR(value)) {
+ mirror = new ErrorMirror(value);
+ } else {
+ mirror = new ObjectMirror(value);
+ }
+
+ mirror_cache_[mirror.handle()] = mirror;
+ return mirror;
}
/**
+ * Returns the mirror for the undefined value.
+ *
+ * @returns {Mirror} the mirror reflects the undefined value
+ */
+function GetUndefinedMirror() {
+ return MakeMirror(void 0);
+}
+
+
+/**
* Inherit the prototype methods from one constructor into another.
*
* The Function.prototype.inherits from lang.js rewritten as a standalone
@@ -87,7 +132,6 @@
const REGEXP_TYPE = 'regexp';
const ERROR_TYPE = 'error';
const PROPERTY_TYPE = 'property';
-const ACCESSOR_TYPE = 'accessor';
const FRAME_TYPE = 'frame';
const SCRIPT_TYPE = 'script';
@@ -155,6 +199,15 @@
/**
+ * Check whether the mirror reflects a value.
+ * @returns {boolean} True if the mirror reflects a value.
+ */
+Mirror.prototype.isValue = function() {
+ return this instanceof ValueMirror;
+}
+
+
+/**
* Check whether the mirror reflects the undefined value.
* @returns {boolean} True if the mirror reflects the undefined value.
*/
@@ -289,18 +342,6 @@
}
-/**
- * Serialize object in JSON format. The actual serialization is handled by the
- * JSONProtocolSerializer.
- * @param {boolean} details Indicate level of details to include
- * @return {string} JSON serialization
- */
-Mirror.prototype.toJSONProtocol = function(details) {
- var serializer = new JSONProtocolSerializer(details)
- return serializer.serialize(this)
-}
-
-
Mirror.prototype.toText = function() {
// Simpel to text which is used when on specialization in subclass.
return "#<" + builtins.GetInstanceName(this.constructor.name) + ">";
@@ -316,11 +357,17 @@
*/
function ValueMirror(type, value) {
Mirror.call(this, type);
+ this.handle_ = next_handle_++;
this.value_ = value;
}
inherits(ValueMirror, Mirror);
+Mirror.prototype.handle = function() {
+ return this.handle_;
+};
+
+
/**
* Check whether this is a primitive value.
* @return {boolean} True if the mirror reflects a primitive value
@@ -335,7 +382,7 @@
};
- /**
+/**
* Get the actual value reflected by this mirror.
* @return {value} The value reflected by this mirror
*/
@@ -581,7 +628,7 @@
}
// Nothing found.
- return new UndefinedMirror();
+ return GetUndefinedMirror();
};
@@ -608,7 +655,7 @@
}
// Nothing found.
- return new UndefinedMirror();
+ return GetUndefinedMirror();
};
@@ -687,8 +734,6 @@
// Return source if function is resolved. Otherwise just fall through to
// return undefined.
if (this.resolved()) {
- // This builtins function is context independant (only uses runtime
- // calls and typeof.
return builtins.FunctionSourceString(this.value_);
}
};
@@ -763,17 +808,17 @@
UnresolvedFunctionMirror.prototype.constructorFunction = function() {
- return new UndefinedMirror();
+ return GetUndefinedMirror();
};
UnresolvedFunctionMirror.prototype.prototypeObject = function() {
- return new UndefinedMirror();
+ return GetUndefinedMirror();
};
UnresolvedFunctionMirror.prototype.protoObject = function() {
- return new UndefinedMirror();
+ return GetUndefinedMirror();
};
@@ -815,7 +860,7 @@
if (details) {
value = new PropertyMirror(this, i, details);
} else {
- value = new UndefinedMirror();
+ value = GetUndefinedMirror();
}
values[i - from_index] = value;
}
@@ -1225,7 +1270,7 @@
// value returned from the VM might be a string if the function for the
// frame is unresolved.
if (IS_FUNCTION(f)) {
- return new FunctionMirror(f);
+ return MakeMirror(f);
} else {
return new UnresolvedFunctionMirror(f);
}
@@ -1345,7 +1390,7 @@
}
// Try to find the function as a property in the receiver. Include the
// prototype chain in the lookup.
- var property = new UndefinedMirror();
+ var property = GetUndefinedMirror();
if (!receiver.isUndefined()) {
for (var r = receiver; !r.isNull() && property.isUndefined(); r = r.protoObject()) {
property = r.lookupProperty(func);
@@ -1526,16 +1571,107 @@
}
+/**
+ * Returns a mirror serializer
+ *
+ * @param {boolean} details Set to true to include details
+ * @returns {MirrorSerializer} mirror serializer
+ */
+function MakeMirrorSerializer(details) {
+ return new JSONProtocolSerializer(details);
+}
+
+
+/**
+ * Object for serializing a mirror objects and its direct references.
+ * @param {boolean} details Indicates whether to include details for the mirror
+ * serialized
+ * @constructor
+ */
function JSONProtocolSerializer(details) {
this.details_ = details;
+ this.mirrors_ = [ ];
}
-JSONProtocolSerializer.prototype.serialize = function(mirror) {
- // Collect the JSON property/value pairs in a array.
+/**
+ * Returns a serialization of an object reference. The referenced object are
+ * added to the serialization state.
+ *
+ * @param {Mirror} mirror The mirror to serialize
+ * @returns {String} JSON serialization
+ */
+JSONProtocolSerializer.prototype.serializeReference = function(mirror) {
+ return this.serialize_(mirror, true, true);
+}
+
+
+/**
+ * Returns a serialization of an object value. The referenced objects are
+ * added to the serialization state.
+ *
+ * @param {Mirror} mirror The mirror to serialize
+ * @returns {String} JSON serialization
+ */
+JSONProtocolSerializer.prototype.serializeValue = function(mirror) {
+ var json = this.serialize_(mirror, false, true);
+ return json;
+}
+
+
+/**
+ * Returns a serialization of all the objects referenced.
+ *
+ * @param {Mirror} mirror The mirror to serialize
+ * @returns {String} JSON serialization
+ */
+JSONProtocolSerializer.prototype.serializeReferencedObjects = function() {
+ // Collect the JSON serialization of the referenced objects in an array.
var content = new Array();
+
+ // Get the number of referenced objects.
+ var count = this.mirrors_.length;
+
+ for (var i = 0; i < count; i++) {
+ content.push(this.serialize_(this.mirrors_[i], false, false));
+ }
- // Always add the type
+ var json = ArrayToJSONArray_(content);
+ return json;
+}
+
+
+JSONProtocolSerializer.prototype.add_ = function(mirror) {
+ // If this mirror is already in the list just return.
+ for (var i = 0; i < this.mirrors_.length; i++) {
+ if (this.mirrors_[i] === mirror) {
+ return;
+ }
+ }
+
+ // Add the mirror to the list of mirrors to be serialized.
+ this.mirrors_.push(mirror);
+}
+
+
+JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
+ details) {
+ // If serializing a reference to a value just return the reference and add the
+ // mirror to the referenced mirrors.
+ if (reference && mirror.isValue()) {
+ this.add_(mirror);
+ return '{ref:' + mirror.handle() + '}';
+ }
+
+ // Collect the JSON property/value pairs in an array.
+ var content = new Array();
+
+ // Add the handle for value mirrors.
+ if (mirror.isValue()) {
+ content.push(MakeJSONPair_('handle', NumberToJSON_(mirror.handle())));
+ }
+
+ // Always add the type.
content.push(MakeJSONPair_('type', StringToJSON_(mirror.type())));
switch (mirror.type()) {
@@ -1573,37 +1709,13 @@
case ERROR_TYPE:
case REGEXP_TYPE:
// Add object representation.
- this.serializeObject_(mirror, content);
+ this.serializeObject_(mirror, content, details);
break;
case PROPERTY_TYPE:
- // Properties are represented by name, value, attributes and type.
- content.push(MakeJSONPair_('name',
- StringToJSON_(mirror.name())));
- content.push(MakeJSONPair_('value',
- mirror.value().toJSONProtocol(this.details_)));
- if (mirror.attributes() != PropertyAttribute.None) {
- content.push(MakeJSONPair_('attributes',
- NumberToJSON_(mirror.attributes())));
- }
- if (mirror.propertyType() != PropertyType.Normal) {
- content.push(MakeJSONPair_('propertyType',
- NumberToJSON_(mirror.propertyType())));
- }
+ throw new Error('PropertyMirror cannot be serialized independeltly')
break;
- case ACCESSOR_TYPE:
- // An accessor can either be native or defined through JavaScript.
- if (mirror.isNative()) {
- content.push(MakeJSONPair_('native', BooleanToJSON_(true)));
- } else {
- content.push(MakeJSONPair_('getter',
- mirror.getter().toJSONProtocol(false)));
- content.push(MakeJSONPair_('setter',
- mirror.setter().toJSONProtocol(false)));
- }
- break;
-
case FRAME_TYPE:
// Add object representation.
this.serializeFrame_(mirror, content);
@@ -1623,7 +1735,6 @@
content.push(MakeJSONPair_('scriptType',
NumberToJSON_(mirror.scriptType())));
break;
-
}
// Always add the text representation.
@@ -1634,86 +1745,121 @@
}
-JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content) {
+/**
+ * Serialize object information to the following JSON format.
+ *
+ * {"className":"<class name>",
+ * "constructorFunction":{"ref":<number>},
+ * "protoObject":{"ref":<number>},
+ * "prototypeObject":{"ref":<number>},
+ * "namedInterceptor":<boolean>,
+ * "indexedInterceptor":<boolean>,
+ * "properties":[<properties>]}
+ */
+JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
+ details) {
+ // Add general object properties.
content.push(MakeJSONPair_('className',
StringToJSON_(mirror.className())));
+ content.push(MakeJSONPair_('constructorFunction',
+ this.serializeReference(mirror.constructorFunction())));
+ content.push(MakeJSONPair_('protoObject',
+ this.serializeReference(mirror.protoObject())));
+ content.push(MakeJSONPair_('prototypeObject',
+ this.serializeReference(mirror.prototypeObject())));
- if (this.details_) {
- content.push(MakeJSONPair_('constructorFunction',
- mirror.constructorFunction().toJSONProtocol(false)));
- content.push(MakeJSONPair_('protoObject',
- mirror.protoObject().toJSONProtocol(false)));
- content.push(MakeJSONPair_('prototypeObject',
- mirror.prototypeObject().toJSONProtocol(false)));
-
- // Add properties. For arrays don't include indexed proeprties.
- var kind = PropertyKind.Named;
- if (!mirror.isArray()) {
- kind |= PropertyKind.Indexed
- }
- var propertyNames = mirror.propertyNames(kind);
- var x = new Array(propertyNames.length);
- for (var i = 0; i < propertyNames.length; i++) {
- x[i] = mirror.property(propertyNames[i]).toJSONProtocol(false);
- }
- content.push(MakeJSONPair_('properties', ArrayToJSONArray_(x)));
-
- // For arrays the indexed properties are added separately and the length is
- // added as well.
- if (mirror.isArray()) {
- var propertyNames = mirror.propertyNames(PropertyKind.Indexed);
- var x = new Array(propertyNames.length);
- for (var i = 0; i < propertyNames.length; i++) {
- x[i] = mirror.property(propertyNames[i]).toJSONProtocol(false);
- }
- content.push(MakeJSONPair_('indexedProperties', ArrayToJSONArray_(x)));
-
- // Add the array length.
- content.push(MakeJSONPair_('length', NumberToJSON_(mirror.length())));
- }
- }
-
+ // Add flags to indicate whether there are interceptors.
if (mirror.hasNamedInterceptor()) {
content.push(MakeJSONPair_('namedInterceptor', BooleanToJSON_(true)));
}
-
if (mirror.hasIndexedInterceptor()) {
content.push(MakeJSONPair_('indexedInterceptor', BooleanToJSON_(true)));
}
+ // Add function specific properties.
if (mirror.isFunction()) {
// Add function specific properties.
content.push(MakeJSONPair_('name', StringToJSON_(mirror.name())));
content.push(MakeJSONPair_('resolved', BooleanToJSON_(mirror.resolved())));
- if (this.details_ && mirror.resolved()) {
+ if (mirror.resolved()) {
content.push(MakeJSONPair_('source', StringToJSON_(mirror.source())));
}
if (mirror.script()) {
- content.push(MakeJSONPair_('script', mirror.script().toJSONProtocol()));
+ content.push(MakeJSONPair_('script', this.serializeValue(mirror.script())));
}
- } else if (mirror.isDate()) {
+ }
+
+ // Add date specific properties.
+ if (mirror.isDate()) {
// Add date specific properties.
content.push(MakeJSONPair_('value', DateToJSON_(mirror.value())));
- } else if (mirror.isRegExp()) {
- // Add regexp specific properties.
- content.push(MakeJSONPair_('source', StringToJSON_(mirror.source())));
- content.push(MakeJSONPair_('global', BooleanToJSON_(mirror.global())));
- content.push(MakeJSONPair_('ignoreCase',
- BooleanToJSON_(mirror.ignoreCase())));
- content.push(MakeJSONPair_('multiline',
- BooleanToJSON_(mirror.multiline())));
- } else if (mirror.isError()) {
- // Add error specific properties.
- content.push(MakeJSONPair_('message', StringToJSON_(mirror.message())));
}
+
+ // Add actual properties - named properties followed by indexed properties.
+ var propertyNames = mirror.propertyNames(PropertyKind.Named);
+ var propertyIndexes = mirror.propertyNames(PropertyKind.Indexed);
+ var p = new Array(propertyNames.length + propertyIndexes.length);
+ for (var i = 0; i < propertyNames.length; i++) {
+ var property_mirror = mirror.property(propertyNames[i]);
+ p[i] = this.serializeProperty_(property_mirror);
+ if (details) {
+ this.add_(property_mirror.value());
+ }
+ }
+ for (var i = 0; i < propertyIndexes.length; i++) {
+ var property_mirror = mirror.property(propertyIndexes[i]);
+ p[propertyNames.length + i] = this.serializeProperty_(property_mirror);
+ if (details) {
+ this.add_(property_mirror.value());
+ }
+ }
+ content.push(MakeJSONPair_('properties', ArrayToJSONArray_(p)));
}
+/**
+ * Serialize property information to the following JSON format for building the
+ * array of properties.
+ *
+ * {"name":"<property name>",
+ * "attributes":<number>,
+ * "propertyType":<number>,
+ * "ref":<number>}
+ *
+ * If the attribute for the property is PropertyAttribute.None it is not added.
+ * If the propertyType for the property is PropertyType.Normal it is not added.
+ * Here are a couple of examples.
+ *
+ * {"name":"hello","ref":1}
+ * {"name":"length","attributes":7,"propertyType":3,"ref":2}
+ *
+ * @param {PropertyMirror} property_mirror The property to serialize
+ * @returns {String} JSON serialization
+ */
+JSONProtocolSerializer.prototype.serializeProperty_ = function(property_mirror) {
+ var builder = new builtins.StringBuilder();
+ builder.add('{"name":');
+ builder.add(StringToJSON_(property_mirror.name()));
+ if (property_mirror.attributes() != PropertyAttribute.None) {
+ builder.add(',"attributes":');
+ builder.add(NumberToJSON_(property_mirror.attributes()));
+ }
+ if (property_mirror.propertyType() != PropertyType.Normal) {
+ builder.add(',"propertyType":');
+ builder.add(NumberToJSON_(property_mirror.propertyType()));
+ }
+ builder.add(',"ref":');
+ builder.add(NumberToJSON_(property_mirror.value().handle()));
+ builder.add('}');
+ return builder.generate();
+}
+
+
JSONProtocolSerializer.prototype.serializeFrame_ = function(mirror, content) {
content.push(MakeJSONPair_('index', NumberToJSON_(mirror.index())));
content.push(MakeJSONPair_('receiver',
- mirror.receiver().toJSONProtocol(false)));
- content.push(MakeJSONPair_('func', mirror.func().toJSONProtocol(false)));
+ this.serializeReference(mirror.receiver())));
+ content.push(MakeJSONPair_('func', this.serializeReference(mirror.func())));
content.push(MakeJSONPair_('constructCall',
BooleanToJSON_(mirror.isConstructCall())));
content.push(MakeJSONPair_('debuggerFrame',
@@ -1726,7 +1872,7 @@
arg.push(MakeJSONPair_('name', StringToJSON_(argument_name)));
}
arg.push(MakeJSONPair_('value',
- mirror.argumentValue(i).toJSONProtocol(false)));
+ this.serializeReference(mirror.argumentValue(i))));
x[i] = ArrayToJSONObject_(arg);
}
content.push(MakeJSONPair_('arguments', ArrayToJSONArray_(x)));
@@ -1734,7 +1880,7 @@
for (var i = 0; i < mirror.localCount(); i++) {
var name = MakeJSONPair_('name', StringToJSON_(mirror.localName(i)));
var value = MakeJSONPair_('value',
- mirror.localValue(i).toJSONProtocol(false));
+ this.serializeReference(mirror.localValue(i)));
x[i] = '{' + name + ',' + value + '}';
}
content.push(MakeJSONPair_('locals', ArrayToJSONArray_(x)));
« no previous file with comments | « src/debug-delay.js ('k') | test/mjsunit/debug-backtrace.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698