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

Reply via email to