Revision: 12477
Author: [email protected]
Date: Mon Sep 10 16:17:04 2012
Log: Introduce InternalProperty type and expose internal properties
for bound functions
Committed: https://code.google.com/p/v8/source/detail?r=12346
Review URL: https://chromiumcodereview.appspot.com/10834376
http://code.google.com/p/v8/source/detail?r=12477
Modified:
/branches/bleeding_edge/src/mirror-debugger.js
/branches/bleeding_edge/test/mjsunit/mirror-object.js
/branches/bleeding_edge/test/mjsunit/mjsunit.status
=======================================
--- /branches/bleeding_edge/src/mirror-debugger.js Tue Aug 21 02:48:26 2012
+++ /branches/bleeding_edge/src/mirror-debugger.js Mon Sep 10 16:17:04 2012
@@ -154,6 +154,7 @@
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 @@
// - RegExpMirror
// - ErrorMirror
// - PropertyMirror
+// - InternalPropertyMirror
// - FrameMirror
// - ScriptMirror
@@ -357,6 +359,15 @@
};
+/**
+ * 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 @@
};
-/**
- * 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 @@
* 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
*/
@@ -714,6 +708,16 @@
return properties;
};
+
+
+/**
+ * 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) {
@@ -787,6 +791,37 @@
}
return '#<' + name + '>';
};
+
+
+/**
+ * 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 [];
+}
/**
@@ -1268,6 +1303,33 @@
};
+/**
+ * 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 @@
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 @@
* "prototypeObject":{"ref":<number>},
* "namedInterceptor":<boolean>,
* "indexedInterceptor":<boolean>,
- * "properties":[<properties>]}
+ * "properties":[<properties>],
+ * "internalProperties":[<internal properties>]}
*/
JSONProtocolSerializer.prototype.serializeObject_ = function(mirror,
content,
details) {
@@ -2288,11 +2352,6 @@
this.serializeReference(mirror.constructorFunction());
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()) {
@@ -2355,6 +2414,15 @@
}
}
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 @@
};
+/**
+ * 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());
=======================================
--- /branches/bleeding_edge/test/mjsunit/mirror-object.js Tue Aug 21
02:48:26 2012
+++ /branches/bleeding_edge/test/mjsunit/mirror-object.js Mon Sep 10
16:17:04 2012
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -49,19 +49,19 @@
JSON.stringify(serializer.serializeReferencedObjects()));
// Check the mirror hierachy.
- assertTrue(mirror instanceof debug.Mirror, 'Unexpected mirror hierachy');
- assertTrue(mirror instanceof debug.ValueMirror, 'Unexpected mirror
hierachy');
- assertTrue(mirror instanceof debug.ObjectMirror, 'Unexpected mirror
hierachy');
+ assertTrue(mirror instanceof debug.Mirror, 'Unexpected mirror
hierarchy');
+ assertTrue(mirror instanceof debug.ValueMirror, 'Unexpected mirror
hierarchy');
+ assertTrue(mirror instanceof debug.ObjectMirror, 'Unexpected mirror
hierarchy');
// Check the mirror properties.
assertTrue(mirror.isObject(), 'Unexpected mirror');
assertEquals('object', mirror.type(), 'Unexpected mirror type');
assertFalse(mirror.isPrimitive(), 'Unexpected primitive mirror');
assertEquals(cls_name, mirror.className(), 'Unexpected mirror class
name');
- assertTrue(mirror.constructorFunction() instanceof
debug.ObjectMirror, 'Unexpected mirror hierachy');
+ assertTrue(mirror.constructorFunction() instanceof
debug.ObjectMirror, 'Unexpected mirror hierarchy');
assertEquals(ctor_name, mirror.constructorFunction().name(), 'Unexpected
constructor function name');
- assertTrue(mirror.protoObject() instanceof debug.Mirror, 'Unexpected
mirror hierachy');
- assertTrue(mirror.prototypeObject() instanceof debug.Mirror, 'Unexpected
mirror hierachy');
+ assertTrue(mirror.protoObject() instanceof debug.Mirror, 'Unexpected
mirror hierarchy');
+ assertTrue(mirror.prototypeObject() instanceof debug.Mirror, 'Unexpected
mirror hierarchy');
assertFalse(mirror.hasNamedInterceptor(), 'No named interceptor
expected');
assertFalse(mirror.hasIndexedInterceptor(), 'No indexed interceptor
expected');
@@ -69,11 +69,18 @@
var properties = mirror.properties();
assertEquals(names.length, properties.length);
for (var i = 0; i < properties.length; i++) {
- assertTrue(properties[i] instanceof debug.Mirror, 'Unexpected mirror
hierachy');
- assertTrue(properties[i] instanceof debug.PropertyMirror, 'Unexpected
mirror hierachy');
+ assertTrue(properties[i] instanceof debug.Mirror, 'Unexpected mirror
hierarchy');
+ assertTrue(properties[i] instanceof debug.PropertyMirror, 'Unexpected
mirror hierarchy');
assertEquals('property', properties[i].type(), 'Unexpected mirror
type');
assertEquals(names[i], properties[i].name(), 'Unexpected property
name');
}
+
+ var internalProperties = mirror.internalProperties();
+ for (var i = 0; i < internalProperties.length; i++) {
+ assertTrue(internalProperties[i] instanceof debug.Mirror, 'Unexpected
mirror hierarchy');
+ assertTrue(internalProperties[i] instanceof
debug.InternalPropertyMirror, 'Unexpected mirror hierarchy');
+ assertEquals('internalProperty',
internalProperties[i].type(), 'Unexpected mirror type');
+ }
for (var p in obj) {
var property_mirror = mirror.property(p);
@@ -172,6 +179,7 @@
testObjectMirror(this.__proto__, 'Object', '');
testObjectMirror([], 'Array', 'Array');
testObjectMirror([1,2], 'Array', 'Array');
+testObjectMirror(Object(17), 'Number', 'Number');
// Test circular references.
o = {};
@@ -230,3 +238,29 @@
assertEquals('a', mirror.property(0).value().value());
assertEquals('b', mirror.property(1).value().value());
assertEquals('c', mirror.property(2).value().value());
+
+// Test value wrapper internal properties.
+mirror = debug.MakeMirror(Object("Capybara"));
+var ip = mirror.internalProperties();
+assertEquals(1, ip.length);
+assertEquals("[[PrimitiveValue]]", ip[0].name());
+assertEquals("string", ip[0].value().type());
+assertEquals("Capybara", ip[0].value().value());
+
+// Test bound function internal properties.
+mirror = debug.MakeMirror(Number.bind(Array, 2));
+ip = mirror.internalProperties();
+assertEquals(3, ip.length);
+var property_map = {};
+for (var i = 0; i < ip.length; i++) {
+ property_map[ip[i].name()] = ip[i];
+}
+assertTrue("[[BoundThis]]" in property_map);
+assertEquals("function", property_map["[[BoundThis]]"].value().type());
+assertEquals(Array, property_map["[[BoundThis]]"].value().value());
+assertTrue("[[TargetFunction]]" in property_map);
+assertEquals("function",
property_map["[[TargetFunction]]"].value().type());
+assertEquals(Number, property_map["[[TargetFunction]]"].value().value());
+assertTrue("[[BoundArgs]]" in property_map);
+assertEquals("object", property_map["[[BoundArgs]]"].value().type());
+assertEquals(1, property_map["[[BoundArgs]]"].value().value().length);
=======================================
--- /branches/bleeding_edge/test/mjsunit/mjsunit.status Wed Aug 1 06:06:08
2012
+++ /branches/bleeding_edge/test/mjsunit/mjsunit.status Mon Sep 10 16:17:04
2012
@@ -85,8 +85,10 @@
array-splice: PASS || TIMEOUT
# Long running test.
-mirror-object: PASS || TIMEOUT
string-indexof-2: PASS || TIMEOUT
+# BUG(2314): Crankshaft generates incorrect (crashing) code on ARM
+# mirror-object: PASS || TIMEOUT
+mirror-object: SKIP
# BUG(3251035): Timeouts in long looping crankshaft optimization
# tests. Skipping because having them timeout takes too long on the
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev