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

Unified Diff: src/debug/mirrors.js

Issue 2644233003: Revert of [debugger api] remove legacy JSON debug protocol. (Closed)
Patch Set: Created 3 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/debug.js ('k') | src/execution.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/debug/mirrors.js
diff --git a/src/debug/mirrors.js b/src/debug/mirrors.js
index 8b050500ff0254419c6df1eca748375d5f039ad1..2713be36b76c9d06fc5fc7c049d5b662b7bff6e3 100644
--- a/src/debug/mirrors.js
+++ b/src/debug/mirrors.js
@@ -2463,11 +2463,577 @@
return this.data_;
};
+
+/**
+ * Returns a mirror serializer
+ *
+ * @param {boolean} details Set to true to include details
+ * @param {Object} options Options comtrolling the serialization
+ * The following options can be set:
+ * includeSource: include ths full source of scripts
+ * @returns {MirrorSerializer} mirror serializer
+ */
+function MakeMirrorSerializer(details, options) {
+ return new JSONProtocolSerializer(details, options);
+}
+
+
+/**
+ * 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, options) {
+ this.details_ = details;
+ this.options_ = options;
+ this.mirrors_ = [ ];
+}
+
+
+/**
+ * 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 {Array.<Object>} Array of the referenced objects converted to
+ * protcol objects.
+ */
+JSONProtocolSerializer.prototype.serializeReferencedObjects = function() {
+ // Collect the protocol representation of the referenced objects in an array.
+ var content = [];
+
+ // 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));
+ }
+
+ return content;
+};
+
+
+JSONProtocolSerializer.prototype.includeSource_ = function() {
+ return this.options_ && this.options_.includeSource;
+};
+
+
+JSONProtocolSerializer.prototype.inlineRefs_ = function() {
+ return this.options_ && this.options_.inlineRefs;
+};
+
+
+JSONProtocolSerializer.prototype.maxStringLength_ = function() {
+ if (IS_UNDEFINED(this.options_) ||
+ IS_UNDEFINED(this.options_.maxStringLength)) {
+ return kMaxProtocolStringLength;
+ }
+ return this.options_.maxStringLength;
+};
+
+
+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);
+};
+
+
+/**
+ * Formats mirror object to protocol reference object with some data that can
+ * be used to display the value in debugger.
+ * @param {Mirror} mirror Mirror to serialize.
+ * @return {Object} Protocol reference object.
+ */
+JSONProtocolSerializer.prototype.serializeReferenceWithDisplayData_ =
+ function(mirror) {
+ var o = {};
+ o.ref = mirror.handle();
+ o.type = mirror.type();
+ switch (mirror.type()) {
+ case MirrorType.UNDEFINED_TYPE:
+ case MirrorType.NULL_TYPE:
+ case MirrorType.BOOLEAN_TYPE:
+ case MirrorType.NUMBER_TYPE:
+ o.value = mirror.value();
+ break;
+ case MirrorType.STRING_TYPE:
+ o.value = mirror.getTruncatedValue(this.maxStringLength_());
+ break;
+ case MirrorType.SYMBOL_TYPE:
+ o.description = mirror.description();
+ break;
+ case MirrorType.FUNCTION_TYPE:
+ o.name = mirror.name();
+ o.inferredName = mirror.inferredName();
+ if (mirror.script()) {
+ o.scriptId = mirror.script().id();
+ }
+ break;
+ case MirrorType.ERROR_TYPE:
+ case MirrorType.REGEXP_TYPE:
+ o.value = mirror.toText();
+ break;
+ case MirrorType.OBJECT_TYPE:
+ o.className = mirror.className();
+ break;
+ }
+ return o;
+};
+
+
+JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
+ details) {
+ // If serializing a reference to a mirror just return the reference and add
+ // the mirror to the referenced mirrors.
+ if (reference &&
+ (mirror.isValue() || mirror.isScript() || mirror.isContext())) {
+ if (this.inlineRefs_() && mirror.isValue()) {
+ return this.serializeReferenceWithDisplayData_(mirror);
+ } else {
+ this.add_(mirror);
+ return {'ref' : mirror.handle()};
+ }
+ }
+
+ // Collect the JSON property/value pairs.
+ var content = {};
+
+ // Add the mirror handle.
+ if (mirror.isValue() || mirror.isScript() || mirror.isContext()) {
+ content.handle = mirror.handle();
+ }
+
+ // Always add the type.
+ content.type = mirror.type();
+
+ switch (mirror.type()) {
+ case MirrorType.UNDEFINED_TYPE:
+ case MirrorType.NULL_TYPE:
+ // Undefined and null are represented just by their type.
+ break;
+
+ case MirrorType.BOOLEAN_TYPE:
+ // Boolean values are simply represented by their value.
+ content.value = mirror.value();
+ break;
+
+ case MirrorType.NUMBER_TYPE:
+ // Number values are simply represented by their value.
+ content.value = NumberToJSON_(mirror.value());
+ break;
+
+ case MirrorType.STRING_TYPE:
+ // String values might have their value cropped to keep down size.
+ if (this.maxStringLength_() != -1 &&
+ mirror.length() > this.maxStringLength_()) {
+ var str = mirror.getTruncatedValue(this.maxStringLength_());
+ content.value = str;
+ content.fromIndex = 0;
+ content.toIndex = this.maxStringLength_();
+ } else {
+ content.value = mirror.value();
+ }
+ content.length = mirror.length();
+ break;
+
+ case MirrorType.SYMBOL_TYPE:
+ content.description = mirror.description();
+ break;
+
+ case MirrorType.OBJECT_TYPE:
+ case MirrorType.FUNCTION_TYPE:
+ case MirrorType.ERROR_TYPE:
+ case MirrorType.REGEXP_TYPE:
+ case MirrorType.PROMISE_TYPE:
+ case MirrorType.GENERATOR_TYPE:
+ // Add object representation.
+ this.serializeObject_(mirror, content, details);
+ break;
+
+ case MirrorType.PROPERTY_TYPE:
+ case MirrorType.INTERNAL_PROPERTY_TYPE:
+ throw %make_error(kDebugger,
+ 'PropertyMirror cannot be serialized independently');
+ break;
+
+ case MirrorType.FRAME_TYPE:
+ // Add object representation.
+ this.serializeFrame_(mirror, content);
+ break;
+
+ case MirrorType.SCOPE_TYPE:
+ // Add object representation.
+ this.serializeScope_(mirror, content);
+ break;
+
+ case MirrorType.SCRIPT_TYPE:
+ // Script is represented by id, name and source attributes.
+ if (mirror.name()) {
+ content.name = mirror.name();
+ }
+ content.id = mirror.id();
+ content.lineOffset = mirror.lineOffset();
+ content.columnOffset = mirror.columnOffset();
+ content.lineCount = mirror.lineCount();
+ if (mirror.data()) {
+ content.data = mirror.data();
+ }
+ if (this.includeSource_()) {
+ content.source = mirror.source();
+ } else {
+ var sourceStart = mirror.source().substring(0, 80);
+ content.sourceStart = sourceStart;
+ }
+ content.sourceLength = mirror.source().length;
+ content.scriptType = mirror.scriptType();
+ content.compilationType = mirror.compilationType();
+ // For compilation type eval emit information on the script from which
+ // eval was called if a script is present.
+ if (mirror.compilationType() == 1 &&
+ mirror.evalFromScript()) {
+ content.evalFromScript =
+ this.serializeReference(mirror.evalFromScript());
+ var evalFromLocation = mirror.evalFromLocation();
+ if (evalFromLocation) {
+ content.evalFromLocation = { line: evalFromLocation.line,
+ column: evalFromLocation.column };
+ }
+ if (mirror.evalFromFunctionName()) {
+ content.evalFromFunctionName = mirror.evalFromFunctionName();
+ }
+ }
+ if (mirror.context()) {
+ content.context = this.serializeReference(mirror.context());
+ }
+ break;
+
+ case MirrorType.CONTEXT_TYPE:
+ content.data = mirror.data();
+ break;
+ }
+
+ // Always add the text representation.
+ content.text = mirror.toText();
+
+ // Create and return the JSON string.
+ return 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>],
+ * "internalProperties":[<internal properties>]}
+ */
+JSONProtocolSerializer.prototype.serializeObject_ = function(mirror, content,
+ details) {
+ // Add general object properties.
+ content.className = mirror.className();
+ content.constructorFunction =
+ this.serializeReference(mirror.constructorFunction());
+ content.protoObject = this.serializeReference(mirror.protoObject());
+ content.prototypeObject = this.serializeReference(mirror.prototypeObject());
+
+ // Add flags to indicate whether there are interceptors.
+ if (mirror.hasNamedInterceptor()) {
+ content.namedInterceptor = true;
+ }
+ if (mirror.hasIndexedInterceptor()) {
+ content.indexedInterceptor = true;
+ }
+
+ if (mirror.isFunction()) {
+ // Add function specific properties.
+ content.name = mirror.name();
+ if (!IS_UNDEFINED(mirror.inferredName())) {
+ content.inferredName = mirror.inferredName();
+ }
+ content.resolved = mirror.resolved();
+ if (mirror.resolved()) {
+ content.source = mirror.source();
+ }
+ if (mirror.script()) {
+ content.script = this.serializeReference(mirror.script());
+ content.scriptId = mirror.script().id();
+
+ serializeLocationFields(mirror.sourceLocation(), content);
+ }
+
+ content.scopes = [];
+ for (var i = 0; i < mirror.scopeCount(); i++) {
+ var scope = mirror.scope(i);
+ content.scopes.push({
+ type: scope.scopeType(),
+ index: i
+ });
+ }
+ }
+
+ if (mirror.isGenerator()) {
+ // Add generator specific properties.
+
+ // Either 'running', 'closed', or 'suspended'.
+ content.status = mirror.status();
+
+ content.func = this.serializeReference(mirror.func())
+ content.receiver = this.serializeReference(mirror.receiver())
+
+ // If the generator is suspended, the content add line/column properties.
+ serializeLocationFields(mirror.sourceLocation(), content);
+
+ // TODO(wingo): Also serialize a reference to the context (scope chain).
+ }
+
+ if (mirror.isDate()) {
+ // Add date specific properties.
+ content.value = mirror.value();
+ }
+
+ if (mirror.isPromise()) {
+ // Add promise specific properties.
+ content.status = mirror.status();
+ content.promiseValue = this.serializeReference(mirror.promiseValue());
+ }
+
+ // Add actual properties - named properties followed by indexed properties.
+ var properties = mirror.propertyNames();
+ for (var i = 0; i < properties.length; i++) {
+ var propertyMirror = mirror.property(properties[i]);
+ properties[i] = this.serializeProperty_(propertyMirror);
+ if (details) {
+ this.add_(propertyMirror.value());
+ }
+ }
+ content.properties = properties;
+
+ 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;
+ }
+};
+
+
+/**
+ * Serialize location information to the following JSON format:
+ *
+ * "position":"<position>",
+ * "line":"<line>",
+ * "column":"<column>",
+ *
+ * @param {SourceLocation} location The location to serialize, may be undefined.
+ */
+function serializeLocationFields (location, content) {
+ if (!location) {
+ return;
+ }
+ content.position = location.position;
+ var line = location.line;
+ if (!IS_UNDEFINED(line)) {
+ content.line = line;
+ }
+ var column = location.column;
+ if (!IS_UNDEFINED(column)) {
+ content.column = column;
+ }
+}
+
+
+/**
+ * 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.
+ * Here are a couple of examples.
+ *
+ * {"name":"hello","propertyType":0,"ref":1}
+ * {"name":"length","attributes":7,"propertyType":3,"ref":2}
+ *
+ * @param {PropertyMirror} propertyMirror The property to serialize.
+ * @returns {Object} Protocol object representing the property.
+ */
+JSONProtocolSerializer.prototype.serializeProperty_ = function(propertyMirror) {
+ var result = {};
+
+ result.name = propertyMirror.name();
+ var propertyValue = propertyMirror.value();
+ if (this.inlineRefs_() && propertyValue.isValue()) {
+ result.value = this.serializeReferenceWithDisplayData_(propertyValue);
+ } else {
+ if (propertyMirror.attributes() != PropertyAttribute.None) {
+ result.attributes = propertyMirror.attributes();
+ }
+ result.propertyType = propertyMirror.propertyType();
+ result.ref = propertyValue.handle();
+ }
+ return result;
+};
+
+
+/**
+ * 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());
+ var func = mirror.func();
+ content.func = this.serializeReference(func);
+ var script = func.script();
+ if (script) {
+ content.script = this.serializeReference(script);
+ }
+ content.constructCall = mirror.isConstructCall();
+ content.atReturn = mirror.isAtReturn();
+ if (mirror.isAtReturn()) {
+ content.returnValue = this.serializeReference(mirror.returnValue());
+ }
+ content.debuggerFrame = mirror.isDebuggerFrame();
+ var x = new GlobalArray(mirror.argumentCount());
+ for (var i = 0; i < mirror.argumentCount(); i++) {
+ var arg = {};
+ var argument_name = mirror.argumentName(i);
+ if (argument_name) {
+ arg.name = argument_name;
+ }
+ arg.value = this.serializeReference(mirror.argumentValue(i));
+ x[i] = arg;
+ }
+ content.arguments = x;
+ var x = new GlobalArray(mirror.localCount());
+ for (var i = 0; i < mirror.localCount(); i++) {
+ var local = {};
+ local.name = mirror.localName(i);
+ local.value = this.serializeReference(mirror.localValue(i));
+ x[i] = local;
+ }
+ content.locals = x;
+ serializeLocationFields(mirror.sourceLocation(), content);
+ var source_line_text = mirror.sourceLineText();
+ if (!IS_UNDEFINED(source_line_text)) {
+ content.sourceLineText = source_line_text;
+ }
+
+ content.scopes = [];
+ for (var i = 0; i < mirror.scopeCount(); i++) {
+ var scope = mirror.scope(i);
+ content.scopes.push({
+ type: scope.scopeType(),
+ index: i
+ });
+ }
+};
+
+
+JSONProtocolSerializer.prototype.serializeScope_ = function(mirror, content) {
+ content.index = mirror.scopeIndex();
+ content.frameIndex = mirror.frameIndex();
+ content.type = mirror.scopeType();
+ content.object = this.inlineRefs_() ?
+ this.serializeValue(mirror.scopeObject()) :
+ this.serializeReference(mirror.scopeObject());
+};
+
+
+/**
+ * Convert a number to a protocol value. For all finite numbers the number
+ * itself is returned. For non finite numbers NaN, Infinite and
+ * -Infinite the string representation "NaN", "Infinite" or "-Infinite"
+ * (not including the quotes) is returned.
+ *
+ * @param {number} value The number value to convert to a protocol value.
+ * @returns {number|string} Protocol value.
+ */
+function NumberToJSON_(value) {
+ if (IsNaN(value)) {
+ return 'NaN';
+ }
+ if (!NUMBER_IS_FINITE(value)) {
+ if (value > 0) {
+ return 'Infinity';
+ } else {
+ return '-Infinity';
+ }
+ }
+ return value;
+}
+
// ----------------------------------------------------------------------------
// Exports
utils.InstallFunctions(global, DONT_ENUM, [
"MakeMirror", MakeMirror,
+ "MakeMirrorSerializer", MakeMirrorSerializer,
"LookupMirror", LookupMirror,
"ToggleMirrorCache", ToggleMirrorCache,
"MirrorCacheIsEmpty", MirrorCacheIsEmpty,
« no previous file with comments | « src/debug/debug.js ('k') | src/execution.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698