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

Unified Diff: src/mirror-delay.js

Issue 123021: Add scope chain information to the debugger (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 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') | src/runtime.h » ('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 2147)
+++ src/mirror-delay.js (working copy)
@@ -34,9 +34,14 @@
Date;
+// Handle id counters.
var next_handle_ = 0;
+var next_transient_handle_ = -1;
+
+// Mirror cache.
var mirror_cache_ = [];
+
/**
* Clear the mirror handle cache.
*/
@@ -50,20 +55,26 @@
* Returns the mirror for a specified value or object.
*
* @param {value or Object} value the value or object to retreive the mirror for
+ * @param {boolean} transient indicate whether this object is transient and
+ * should not be added to the mirror cache. The default is not transient.
* @returns {Mirror} the mirror reflects the passed value or object
*/
-function MakeMirror(value) {
+function MakeMirror(value, opt_transient) {
var mirror;
- for (id in mirror_cache_) {
- mirror = mirror_cache_[id];
- if (mirror.value() === value) {
- return mirror;
+
+ // Look for non transient mirrors in the mirror cache.
+ if (!opt_transient) {
+ for (id in mirror_cache_) {
+ mirror = mirror_cache_[id];
+ if (mirror.value() === value) {
+ return mirror;
+ }
+ // Special check for NaN as NaN == NaN is false.
+ if (mirror.isNumber() && isNaN(mirror.value()) &&
+ typeof value == 'number' && isNaN(value)) {
+ return mirror;
+ }
}
- // Special check for NaN as NaN == NaN is false.
- if (mirror.isNumber() && isNaN(mirror.value()) &&
- typeof value == 'number' && isNaN(value)) {
- return mirror;
- }
}
if (IS_UNDEFINED(value)) {
@@ -89,7 +100,7 @@
} else if (IS_SCRIPT(value)) {
mirror = new ScriptMirror(value);
} else {
- mirror = new ObjectMirror(value);
+ mirror = new ObjectMirror(value, OBJECT_TYPE, opt_transient);
}
mirror_cache_[mirror.handle()] = mirror;
@@ -155,6 +166,7 @@
const FRAME_TYPE = 'frame';
const SCRIPT_TYPE = 'script';
const CONTEXT_TYPE = 'context';
+const SCOPE_TYPE = 'scope';
// Maximum length when sending strings through the JSON protocol.
const kMaxProtocolStringLength = 80;
@@ -185,6 +197,13 @@
PropertyAttribute.DontDelete = DONT_DELETE;
+// A copy of the scope types from runtime.cc.
+ScopeType = { Global: 0,
+ Local: 1,
+ With: 2,
+ Closure: 3 };
+
+
// Mirror hierarchy:
// - Mirror
// - ValueMirror
@@ -373,6 +392,15 @@
/**
+ * Check whether the mirror reflects a scope.
+ * @returns {boolean} True if the mirror reflects a scope
+ */
+Mirror.prototype.isScope = function() {
+ return this instanceof ScopeMirror;
+}
+
+
+/**
* Allocate a handle id for this object.
*/
Mirror.prototype.allocateHandle_ = function() {
@@ -380,6 +408,15 @@
}
+/**
+ * Allocate a transient handle id for this object. Transient handles are
+ * negative.
+ */
+Mirror.prototype.allocateTransientHandle_ = function() {
+ this.handle_ = next_transient_handle_--;
+}
+
+
Mirror.prototype.toText = function() {
// Simpel to text which is used when on specialization in subclass.
return "#<" + builtins.GetInstanceName(this.constructor.name) + ">";
@@ -390,13 +427,19 @@
* Base class for all value mirror objects.
* @param {string} type The type of the mirror
* @param {value} value The value reflected by this mirror
+ * @param {boolean} transient indicate whether this object is transient with a
+ * transient handle
* @constructor
* @extends Mirror
*/
-function ValueMirror(type, value) {
+function ValueMirror(type, value, transient) {
Mirror.call(this, type);
this.value_ = value;
- this.allocateHandle_();
+ if (!transient) {
+ this.allocateHandle_();
+ } else {
+ this.allocateTransientHandle_();
+ }
}
inherits(ValueMirror, Mirror);
@@ -525,11 +568,13 @@
/**
* Mirror object for objects.
* @param {object} value The object reflected by this mirror
+ * @param {boolean} transient indicate whether this object is transient with a
+ * transient handle
* @constructor
* @extends ValueMirror
*/
-function ObjectMirror(value, type) {
- ValueMirror.call(this, type || OBJECT_TYPE, value);
+function ObjectMirror(value, type, transient) {
+ ValueMirror.call(this, type || OBJECT_TYPE, value, transient);
}
inherits(ObjectMirror, ValueMirror);
@@ -1080,7 +1125,7 @@
PropertyMirror.prototype.value = function() {
- return MakeMirror(this.value_);
+ return MakeMirror(this.value_, false);
}
@@ -1135,7 +1180,7 @@
if (this.hasGetter()) {
return MakeMirror(this.getter_);
} else {
- return new UndefinedMirror();
+ return GetUndefinedMirror();
}
}
@@ -1149,7 +1194,7 @@
if (this.hasSetter()) {
return MakeMirror(this.setter_);
} else {
- return new UndefinedMirror();
+ return GetUndefinedMirror();
}
}
@@ -1294,6 +1339,11 @@
}
+FrameDetails.prototype.scopeCount = function() {
+ return %GetScopeCount(this.break_id_, this.frameId());
+}
+
+
/**
* Mirror object for stack frames.
* @param {number} break_id The break id in the VM for which this frame is
@@ -1419,6 +1469,16 @@
};
+FrameMirror.prototype.scopeCount = function() {
+ return this.details_.scopeCount();
+};
+
+
+FrameMirror.prototype.scope = function(index) {
+ return new ScopeMirror(this, index);
+};
+
+
FrameMirror.prototype.evaluate = function(source, disable_break) {
var result = %DebugEvaluate(this.break_id_, this.details_.frameId(),
source, Boolean(disable_break));
@@ -1562,7 +1622,71 @@
}
+const kScopeDetailsTypeIndex = 0;
+const kScopeDetailsObjectIndex = 1;
+
+function ScopeDetails(frame, index) {
+ this.break_id_ = frame.break_id_;
+ this.details_ = %GetScopeDetails(frame.break_id_,
+ frame.details_.frameId(),
+ index);
+}
+
+
+ScopeDetails.prototype.type = function() {
+ %CheckExecutionState(this.break_id_);
+ return this.details_[kScopeDetailsTypeIndex];
+}
+
+
+ScopeDetails.prototype.object = function() {
+ %CheckExecutionState(this.break_id_);
+ return this.details_[kScopeDetailsObjectIndex];
+}
+
+
/**
+ * Mirror object for scope.
+ * @param {FrameMirror} frame The frame this scope is a part of
+ * @param {number} index The scope index in the frame
+ * @constructor
+ * @extends Mirror
+ */
+function ScopeMirror(frame, index) {
+ Mirror.call(this, SCOPE_TYPE);
+ this.frame_index_ = frame.index_;
+ this.scope_index_ = index;
+ this.details_ = new ScopeDetails(frame, index);
+}
+inherits(ScopeMirror, Mirror);
+
+
+ScopeMirror.prototype.frameIndex = function() {
+ return this.frame_index_;
+};
+
+
+ScopeMirror.prototype.scopeIndex = function() {
+ return this.scope_index_;
+};
+
+
+ScopeMirror.prototype.scopeType = function() {
+ return this.details_.type();
+};
+
+
+ScopeMirror.prototype.scopeObject = function() {
+ // For local and closure scopes create a transient mirror as these objects are
+ // created on the fly materializing the local or closure scopes and
+ // therefore will not preserve identity.
+ var transient = this.scopeType() == ScopeType.Local ||
+ this.scopeType() == ScopeType.Closure;
+ return MakeMirror(this.details_.object(), transient);
+};
+
+
+/**
* Mirror object for script source.
* @param {Script} script The script object
* @constructor
@@ -1829,6 +1953,7 @@
return o;
};
+
JSONProtocolSerializer.prototype.serialize_ = function(mirror, reference,
details) {
// If serializing a reference to a mirror just return the reference and add
@@ -1900,6 +2025,11 @@
this.serializeFrame_(mirror, content);
break;
+ case SCOPE_TYPE:
+ // Add object representation.
+ this.serializeScope_(mirror, content);
+ break;
+
case SCRIPT_TYPE:
// Script is represented by id, name and source attributes.
if (mirror.name()) {
@@ -2102,6 +2232,14 @@
}
+JSONProtocolSerializer.prototype.serializeScope_ = function(mirror, content) {
+ content.index = mirror.scopeIndex();
+ content.frameIndex = mirror.frameIndex();
+ content.type = mirror.scopeType();
+ content.object = 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
« no previous file with comments | « src/debug-delay.js ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698