Author: [email protected]
Date: Tue Jan 13 06:38:44 2009
New Revision: 1068

Modified:
    branches/bleeding_edge/src/mirror-delay.js
    branches/bleeding_edge/src/runtime.cc
    branches/bleeding_edge/test/cctest/test-debug.cc
    branches/bleeding_edge/test/mjsunit/mirror-object.js

Log:
Refactored the mirror representation of properties. Removed the  
AssessorMirror and InterceptorPropertyMirror and moved all reflection for  
properties to PropertyMirror. From a PropertyMirror it can be checked  
whether a property has getter/setter defined in JavaScript and information  
on the getter/setter functions are now available. If calling the getter  
resulted in an exception this is reflected as well.

Properties from interceptors are also reflected through PropertyMirror as  
the distinction did not make sense seen from a JavaScript debugging  
perspective. The isNative function on a PropertyMirror can be used to check  
whether a property is defined natively by the host (or V8).

Simplified the local property lookup in the debug runtime call to just call  
GetProperty as the property is known to be a local property.
Review URL: http://codereview.chromium.org/17377

Modified: branches/bleeding_edge/src/mirror-delay.js
==============================================================================
--- branches/bleeding_edge/src/mirror-delay.js  (original)
+++ branches/bleeding_edge/src/mirror-delay.js  Tue Jan 13 06:38:44 2009
@@ -135,8 +135,6 @@
  //         - RegExpMirror
  //         - ErrorMirror
  //     - PropertyMirror
-//       - InterceptorPropertyMirror
-//     - AccessorMirror
  //     - FrameMirror
  //     - ScriptMirror

@@ -274,25 +272,6 @@


  /**
- * Check whether the mirror reflects a property from an interceptor.
- * @returns {boolean} True if the mirror reflects a property from an
- *     interceptor
- */
-Mirror.prototype.isInterceptorProperty = function() {
-  return this instanceof InterceptorPropertyMirror;
-}
-
-
-/**
- * Check whether the mirror reflects an accessor.
- * @returns {boolean} True if the mirror reflects an accessor
- */
-Mirror.prototype.isAccessor = function() {
-  return this instanceof AccessorMirror;
-}
-
-
-/**
   * Check whether the mirror reflects a stack frame.
   * @returns {boolean} True if the mirror reflects a stack frame
   */
@@ -519,13 +498,39 @@
    var propertyNames;
    var elementNames;
    var total = 0;
+
+  // Find all the named properties.
    if (kind & PropertyKind.Named) {
+    // Get the local property names.
      propertyNames = %DebugLocalPropertyNames(this.value_);
      total += propertyNames.length;
+
+    // Get names for named interceptor properties if any.
+    if (this.hasNamedInterceptor() && (kind & PropertyKind.Named)) {
+      var namedInterceptorNames =
+          %DebugNamedInterceptorPropertyNames(this.value_);
+      if (namedInterceptorNames) {
+        propertyNames = propertyNames.concat(namedInterceptorNames);
+        total += namedInterceptorNames.length;
+      }
+    }
    }
+
+  // Find all the indexed properties.
    if (kind & PropertyKind.Indexed) {
-    elementNames = %DebugLocalElementNames(this.value_)
+    // Get the local element names.
+    elementNames = %DebugLocalElementNames(this.value_);
      total += elementNames.length;
+
+    // Get names for indexed interceptor properties.
+    if (this.hasIndexedInterceptor() && (kind & PropertyKind.Indexed)) {
+      var indexedInterceptorNames =
+          %DebugIndexedInterceptorElementNames(this.value_);
+      if (indexedInterceptorNames) {
+        elementNames = elementNames.concat(indexedInterceptorNames);
+        total += indexedInterceptorNames.length;
+      }
+    }
    }
    limit = Math.min(limit || total, total);

@@ -569,95 +574,10 @@
  };


-/**
- * Return the interceptor property names for this object.
- * @param {number} kind Indicate whether named, indexed or both kinds of
- *     interceptor properties are requested
- * @param {number} limit Limit the number of names returend to the  
specified
-       value
- * @return {Array} interceptor property names for this object
- */
-ObjectMirror.prototype.interceptorPropertyNames = function(kind, limit) {
-  // Find kind.
-  kind = kind || PropertyKind.Named | PropertyKind.Indexed;
-  var namedInterceptorNames;
-  var indexedInterceptorNames;
-
-  // Get names for named interceptor properties.
-  if (this.hasNamedInterceptor() && kind & PropertyKind.Named) {
-    namedInterceptorNames  
= %DebugNamedInterceptorPropertyNames(this.value_);
-  }
-
-  // Get names for indexed interceptor properties.
-  if (this.hasIndexedInterceptor() && kind & PropertyKind.Indexed) {
-    indexedInterceptorNames  
= %DebugIndexedInterceptorElementNames(this.value_);
-  }
-
-  // Return either retult or both concattenated.
-  if (namedInterceptorNames && indexedInterceptorNames) {
-    return namedInterceptorNames.concat(indexedInterceptorNames);
-  } else if (namedInterceptorNames) {
-    return namedInterceptorNames;
-  } else if (indexedInterceptorNames) {
-    return indexedInterceptorNames;
-  } else {
-    return new Array(0);
-  }
-};
-
-
-/**
- * Return interceptor properties this object.
- * @param {number} opt_kind Indicate whether named, indexed or both kinds  
of
- *     interceptor properties are requested
- * @param {Array} opt_names Limit the number of properties returned to the
-       specified value
- * @return {Array} properties this object as an array of PropertyMirror  
objects
- */
-ObjectMirror.prototype.interceptorProperties = function(opt_kind,  
opt_names) {
-  // Find kind.
-  var kind = opt_kind || PropertyKind.Named | PropertyKind.Indexed;
-  var namedInterceptorProperties;
-  var indexedInterceptorProperties;
-
-  // Get values for named interceptor properties.
-  if (kind & PropertyKind.Named) {
-    var names = opt_names ||  
this.interceptorPropertyNames(PropertyKind.Named);
-    namedInterceptorProperties = new Array(names.length);
-    for (i = 0; i < names.length; i++) {
-      var value = %DebugNamedInterceptorPropertyValue(this.value_,  
names[i]);
-      namedInterceptorProperties[i] = new InterceptorPropertyMirror(this,  
names[i], value);
-    }
-  }
-
-  // Get values for indexed interceptor properties.
-  if (kind & PropertyKind.Indexed) {
-    var names = opt_names ||  
this.interceptorPropertyNames(PropertyKind.Indexed);
-    indexedInterceptorProperties = new Array(names.length);
-    for (i = 0; i < names.length; i++) {
-      // Don't try to get the value if the name is not a number.
-      if (IS_NUMBER(names[i])) {
-        var value = %DebugIndexedInterceptorElementValue(this.value_,  
names[i]);
-        indexedInterceptorProperties[i] = new  
InterceptorPropertyMirror(this, names[i], value);
-      }
-    }
-  }
-
-  // Return either result or both concattenated.
-  if (namedInterceptorProperties && indexedInterceptorProperties) {
-    return namedInterceptorProperties.concat(indexedInterceptorProperties);
-  } else if (namedInterceptorProperties) {
-    return namedInterceptorProperties;
-  } else {
-    return indexedInterceptorProperties;
-  }
-};
-
-
  ObjectMirror.prototype.property = function(name) {
    var details = %DebugGetPropertyDetails(this.value_, %ToString(name));
    if (details) {
-    return new PropertyMirror(this, name, details[0], details[1]);
+    return new PropertyMirror(this, name, details);
    }

    // Nothing found.
@@ -893,7 +813,7 @@
      var details = %DebugGetPropertyDetails(this.value_, %ToString(i));
      var value;
      if (details) {
-      value = new PropertyMirror(this, i, details[0], details[1]);
+      value = new PropertyMirror(this, i, details);
      } else {
        value = new UndefinedMirror();
      }
@@ -1011,16 +931,21 @@
   * Base mirror object for properties.
   * @param {ObjectMirror} mirror The mirror object having this property
   * @param {string} name The name of the property
- * @param {Object} value The value of the property
+ * @param {Array} details Details about the property
   * @constructor
   * @extends Mirror
   */
-function PropertyMirror(mirror, name, value, details) {
+function PropertyMirror(mirror, name, details) {
    Mirror.call(this, PROPERTY_TYPE);
    this.mirror_ = mirror;
    this.name_ = name;
-  this.value_ = value;
-  this.details_ = details;
+  this.value_ = details[0];
+  this.details_ = details[1];
+  if (details.length > 2) {
+    this.exception_ = details[2]
+    this.getter_ = details[3];
+    this.setter_ = details[4];
+  }
  }
  inherits(PropertyMirror, Mirror);

@@ -1056,14 +981,16 @@


  PropertyMirror.prototype.value = function() {
-  if (this.propertyType() == PropertyType.Callbacks) {
-    // TODO(1242933): AccessorMirror should have getter/setter values.
-    return new AccessorMirror();
-  } else if (this.type() == PropertyType.Interceptor) {
-    return new UndefinedMirror();
-  } else {
-    return MakeMirror(this.value_);
-  }
+  return MakeMirror(this.value_);
+}
+
+
+/**
+ * Returns whether this property value is an exception.
+ * @return {booolean} True if this property value is an exception
+ */
+PropertyMirror.prototype.isException = function() {
+  return this.exception_ ? true : false;
  }


@@ -1083,62 +1010,61 @@


  /**
- * Mirror object for interceptor named properties.
- * @param {ObjectMirror} mirror The mirror object having this property
- * @param {String} name The name of the property
- * @param {value} value The value of the property
- * @constructor
- * @extends PropertyMirror
+ * Returns whether this property has a getter defined through  
__defineGetter__.
+ * @return {booolean} True if this property has a getter
   */
-function InterceptorPropertyMirror(mirror, name, value) {
-  PropertyMirror.call(this, mirror, name, value, PropertyType.Interceptor);
+PropertyMirror.prototype.hasGetter = function() {
+  return this.getter_ ? true : false;
  }
-inherits(InterceptorPropertyMirror, PropertyMirror);


  /**
- * Mirror object for property accessors.
- * @param {Function} getter The getter function for this accessor
- * @param {Function} setter The setter function for this accessor
- * @constructor
- * @extends Mirror
+ * Returns whether this property has a setter defined through  
__defineSetter__.
+ * @return {booolean} True if this property has a setter
   */
-function AccessorMirror(getter, setter) {
-  Mirror.call(this, ACCESSOR_TYPE);
-  this.getter_ = getter;
-  this.setter_ = setter;
+PropertyMirror.prototype.hasSetter = function() {
+  return this.setter_ ? true : false;
  }
-inherits(AccessorMirror, Mirror);


  /**
- * Returns whether this accessor is native or not. A native accessor is  
either
- * a VM buildin or provided through the API. A non native accessor is  
defined
- * in JavaScript using the __defineGetter__ and/or __defineGetter__  
functions.
- * @return {boolean} True is the accessor is native
+ * Returns the getter for this property defined through __defineGetter__.
+ * @return {Mirror} FunctionMirror reflecting the getter function or
+ *     UndefinedMirror if there is no getter for this property
   */
-AccessorMirror.prototype.isNative = function() {
-  return IS_UNDEFINED(this.getter_) && IS_UNDEFINED(this.setter_);
+PropertyMirror.prototype.getter = function() {
+  if (this.hasGetter()) {
+    return MakeMirror(this.getter_);
+  } else {
+    return new UndefinedMirror();
+  }
  }


  /**
- * Returns a mirror for the function of a non native getter.
- * @return {FunctionMirror} Function mirror for the getter set using
- *     __defineGetter__.
- */
-AccessorMirror.prototype.getter = function(details) {
-  return MakeMirror(this.getter_);
+ * Returns the setter for this property defined through __defineSetter__.
+ * @return {Mirror} FunctionMirror reflecting the setter function or
+ *     UndefinedMirror if there is no setter for this property
+ */
+PropertyMirror.prototype.setter = function() {
+  if (this.hasSetter()) {
+    return MakeMirror(this.setter_);
+  } else {
+    return new UndefinedMirror();
+  }
  }


  /**
- * Returns a mirror for the function of a non native setter.
- * @return {FunctionMirror} Function mirror for the getter set using
- *     __defineSetter__.
- */
-AccessorMirror.prototype.setter = function(details) {
-  return MakeMirror(this.setter_);
+ * Returns whether this property is natively implemented by the host or a  
set
+ * through JavaScript code.
+ * @return {boolean} True if the property is
+ *     UndefinedMirror if there is no setter for this property
+ */
+PropertyMirror.prototype.isNative = function() {
+  return (this.propertyType() == PropertyType.Interceptor) ||
+         ((this.propertyType() == PropertyType.Callbacks) &&
+          !this.hasGetter() && !this.hasSetter());
  }


@@ -1731,14 +1657,6 @@
        x[i] = mirror.property(propertyNames[i]).toJSONProtocol(false);
      }
      content.push(MakeJSONPair_('properties', ArrayToJSONArray_(x)));
-
-    // Add interceptor properties.
-    propertyNames = mirror.interceptorPropertyNames();
-    var x = new Array(propertyNames.length);
-    for (var i = 0; i < propertyNames.length; i++) {
-      x[i] = properties[i].toJSONProtocol(details);
-    }
-    content.push(MakeJSONPair_('interceptorProperties',  
ArrayToJSONArray_(x)));

      // For arrays the indexed properties are added separately and the  
length is
      // added as well.

Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc       (original)
+++ branches/bleeding_edge/src/runtime.cc       Tue Jan 13 06:38:44 2009
@@ -4503,30 +4503,32 @@
  }


-static Object* DebugLookupResultValue(LookupResult* result) {
-  Object* value;
+static Object* DebugLookupResultValue(Object* obj, String* name,
+                                      LookupResult* result,
+                                      bool* caught_exception) {
    switch (result->type()) {
-    case NORMAL: {
-      Dictionary* dict =
-          JSObject::cast(result->holder())->property_dictionary();
-      value = dict->ValueAt(result->GetDictionaryEntry());
-      if (value->IsTheHole()) {
-        return Heap::undefined_value();
-      }
-      return value;
-    }
+    case NORMAL:
      case FIELD:
-      value =
-          JSObject::cast(
-              result->holder())->FastPropertyAt(result->GetFieldIndex());
-      if (value->IsTheHole()) {
-        return Heap::undefined_value();
+    case CONSTANT_FUNCTION:
+      return obj->GetProperty(name);
+    case CALLBACKS: {
+      // Get the property value. If there is an exception it must be thown  
from
+      // a JavaScript getter.
+      Object* value;
+      value = obj->GetProperty(name);
+      if (value->IsException()) {
+        if (caught_exception != NULL) {
+          *caught_exception = true;
+        }
+        value = Top::pending_exception();
+        Top::optional_reschedule_exception(true);
        }
+      ASSERT(!Top::has_pending_exception());
+      ASSERT(!Top::external_caught_exception());
        return value;
-    case CONSTANT_FUNCTION:
-      return result->GetConstantFunction();
-    case CALLBACKS:
+    }
      case INTERCEPTOR:
+      return obj->GetProperty(name);
      case MAP_TRANSITION:
      case CONSTANT_TRANSITION:
      case NULL_DESCRIPTOR:
@@ -4539,6 +4541,18 @@
  }


+// Get debugger related details for an object property.
+// args[0]: object holding property
+// args[1]: name of the property
+//
+// The array returned contains the following information:
+// 0: Property value
+// 1: Property details
+// 2: Property value is exception
+// 3: Getter function if defined
+// 4: Setter function if defined
+// Items 2-4 are only filled if the property has either a getter or a  
setter
+// defined through __defineGetter__ and/or __defineSetter__.
  static Object* Runtime_DebugGetPropertyDetails(Arguments args) {
    HandleScope scope;

@@ -4559,12 +4573,26 @@

    // Perform standard local lookup on the object.
    LookupResult result;
-  obj->Lookup(*name, &result);
+  obj->LocalLookup(*name, &result);
    if (result.IsProperty()) {
-    Handle<Object> value(DebugLookupResultValue(&result));
-    Handle<FixedArray> details = Factory::NewFixedArray(2);
+    bool caught_exception = false;
+    Handle<Object> value(DebugLookupResultValue(*obj, *name, &result,
+                                                &caught_exception));
+    // If the callback object is a fixed array then it contains JavaScript
+    // getter and/or setter.
+    bool hasJavaScriptAccessors = result.type() == CALLBACKS &&
+                                   
result.GetCallbackObject()->IsFixedArray();
+    Handle<FixedArray> details =
+        Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
      details->set(0, *value);
      details->set(1, result.GetPropertyDetails().AsSmi());
+    if (hasJavaScriptAccessors) {
+      details->set(2,
+                   caught_exception ? Heap::true_value() :  
Heap::false_value());
+      details->set(3,  
FixedArray::cast(result.GetCallbackObject())->get(0));
+      details->set(4,  
FixedArray::cast(result.GetCallbackObject())->get(1));
+    }
+
      return *Factory::NewJSArrayWithElements(details);
    }
    return Heap::undefined_value();
@@ -4582,7 +4610,7 @@
    LookupResult result;
    obj->Lookup(*name, &result);
    if (result.IsProperty()) {
-    return DebugLookupResultValue(&result);
+    return DebugLookupResultValue(*obj, *name, &result, NULL);
    }
    return Heap::undefined_value();
  }
@@ -4676,10 +4704,11 @@
    HandleScope scope;
    ASSERT(args.length() == 1);
    CONVERT_ARG_CHECKED(JSObject, obj, 0);
-  RUNTIME_ASSERT(obj->HasNamedInterceptor());

-  v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
-  if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
+  if (obj->HasNamedInterceptor()) {
+    v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
+    if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
+  }
    return Heap::undefined_value();
  }

@@ -4690,10 +4719,11 @@
    HandleScope scope;
    ASSERT(args.length() == 1);
    CONVERT_ARG_CHECKED(JSObject, obj, 0);
-  RUNTIME_ASSERT(obj->HasIndexedInterceptor());

-  v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
-  if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
+  if (obj->HasIndexedInterceptor()) {
+    v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
+    if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
+  }
    return Heap::undefined_value();
  }


Modified: branches/bleeding_edge/test/cctest/test-debug.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-debug.cc    (original)
+++ branches/bleeding_edge/test/cctest/test-debug.cc    Tue Jan 13 06:38:44  
2009
@@ -2660,58 +2660,76 @@

    // Get the property names from the interceptors
    CompileRun(
-      "named_names = named_mirror.interceptorPropertyNames();"
-      "indexed_names = indexed_mirror.interceptorPropertyNames();"
-      "both_names = both_mirror.interceptorPropertyNames()");
+      "named_names = named_mirror.propertyNames();"
+      "indexed_names = indexed_mirror.propertyNames();"
+      "both_names = both_mirror.propertyNames()");
    CHECK_EQ(3, CompileRun("named_names.length")->Int32Value());
    CHECK_EQ(2, CompileRun("indexed_names.length")->Int32Value());
    CHECK_EQ(5, CompileRun("both_names.length")->Int32Value());

    // Check the expected number of properties.
    const char* source;
-  source = "named_mirror.interceptorProperties().length";
+  source = "named_mirror.properties().length";
    CHECK_EQ(3, CompileRun(source)->Int32Value());

-  source = "indexed_mirror.interceptorProperties().length";
+  source = "indexed_mirror.properties().length";
    CHECK_EQ(2, CompileRun(source)->Int32Value());

-  source = "both_mirror.interceptorProperties().length";
+  source = "both_mirror.properties().length";
    CHECK_EQ(5, CompileRun(source)->Int32Value());

-  source = "both_mirror.interceptorProperties(1).length";
+  // 1 is PropertyKind.Named;
+  source = "both_mirror.properties(1).length";
    CHECK_EQ(3, CompileRun(source)->Int32Value());

-  source = "both_mirror.interceptorProperties(2).length";
+  // 2 is PropertyKind.Indexed;
+  source = "both_mirror.properties(2).length";
    CHECK_EQ(2, CompileRun(source)->Int32Value());

-  source = "both_mirror.interceptorProperties(3).length";
+  // 3 is PropertyKind.Named  | PropertyKind.Indexed;
+  source = "both_mirror.properties(3).length";
    CHECK_EQ(5, CompileRun(source)->Int32Value());

-  // Get the interceptor properties for the object with both types of
-  // interceptors.
-  CompileRun("both_values = both_mirror.interceptorProperties()");
-
-  // Check the mirror hierachy
-  source = "both_values[0] instanceof debug.PropertyMirror";
-  CHECK(CompileRun(source)->BooleanValue());
-
-  source = "both_values[0] instanceof debug.InterceptorPropertyMirror";
-  CHECK(CompileRun(source)->BooleanValue());
+  // Get the interceptor properties for the object with only named  
interceptor.
+  CompileRun("named_values = named_mirror.properties()");

-  source = "both_values[1] instanceof debug.InterceptorPropertyMirror";
-  CHECK(CompileRun(source)->BooleanValue());
+  // Check that the properties are interceptor properties.
+  for (int i = 0; i < 3; i++) {
+    EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
+    OS::SNPrintF(buffer,
+                 "named_values[%d] instanceof debug.PropertyMirror", i);
+    CHECK(CompileRun(buffer.start())->BooleanValue());
+
+    // 4 is PropertyType.Interceptor
+    OS::SNPrintF(buffer, "named_values[%d].propertyType()", i);
+    CHECK_EQ(4, CompileRun(buffer.start())->Int32Value());
+
+    OS::SNPrintF(buffer, "named_values[%d].isNative()", i);
+    CHECK(CompileRun(buffer.start())->BooleanValue());
+  }
+
+  // Get the interceptor properties for the object with only indexed
+  // interceptor.
+  CompileRun("indexed_values = indexed_mirror.properties()");
+
+  // Check that the properties are interceptor properties.
+  for (int i = 0; i < 2; i++) {
+    EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
+    OS::SNPrintF(buffer,
+                 "indexed_values[%d] instanceof debug.PropertyMirror", i);
+    CHECK(CompileRun(buffer.start())->BooleanValue());
+  }

-  source = "both_values[2] instanceof debug.InterceptorPropertyMirror";
-  CHECK(CompileRun(source)->BooleanValue());
-
-  source = "both_values[3] instanceof debug.PropertyMirror";
-  CHECK(CompileRun(source)->BooleanValue());
-
-  source = "both_values[3] instanceof debug.InterceptorPropertyMirror";
-  CHECK(CompileRun(source)->BooleanValue());
+  // Get the interceptor properties for the object with both types of
+  // interceptors.
+  CompileRun("both_values = both_mirror.properties()");

-  source = "both_values[4] instanceof debug.InterceptorPropertyMirror";
-  CHECK(CompileRun(source)->BooleanValue());
+  // Check that the properties are interceptor properties.
+  for (int i = 0; i < 5; i++) {
+    EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
+    OS::SNPrintF(buffer, "both_values[%d] instanceof  
debug.PropertyMirror", i);
+    CHECK(CompileRun(buffer.start())->BooleanValue());
+  }

    // Check the property names.
    source = "both_values[0].name() == 'a'";

Modified: branches/bleeding_edge/test/mjsunit/mirror-object.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/mirror-object.js        (original)
+++ branches/bleeding_edge/test/mjsunit/mirror-object.js        Tue Jan 13  
06:38:44 2009
@@ -107,8 +107,7 @@
          } else {
            assertTrue(typeof(fromJSON.properties[i].attributes)  
=== 'undefined');
          }
-        if (!properties[i].value() instanceof debug.AccessorMirror &&
-            properties[i].value().isPrimitive()) {
+        if (!properties[i].value().isPrimitive()) {
            // NaN is not equal to NaN.
            if (isNaN(properties[i].value().value())) {
              assertTrue(isNaN(fromJSON.properties[i].value.value));
@@ -157,27 +156,46 @@

  // Test objects with JavaScript accessors.
  o = {}
-o.__defineGetter__('a', function(){throw 'a';})
-o.__defineSetter__('b', function(){throw 'b';})
-o.__defineGetter__('c', function(){throw 'c';})
-o.__defineSetter__('c', function(){throw 'c';})
+o.__defineGetter__('a', function(){return 'a';});
+o.__defineSetter__('b', function(){});
+o.__defineGetter__('c', function(){throw 'c';});
+o.__defineSetter__('c', function(){throw 'c';});
  testObjectMirror(o, 'Object', 'Object');
  mirror = debug.MakeMirror(o);
  // a has getter but no setter.
-assertTrue(mirror.property('a').value() instanceof debug.AccessorMirror);
+assertTrue(mirror.property('a').hasGetter());
+assertFalse(mirror.property('a').hasSetter());
  assertEquals(debug.PropertyType.Callbacks,  
mirror.property('a').propertyType());
+assertEquals('function', mirror.property('a').getter().type());
+assertEquals('undefined', mirror.property('a').setter().type());
+assertEquals('function (){return \'a\';}',  
mirror.property('a').getter().source());
+assertEquals('a', mirror.property('a').value().value());
+assertFalse(mirror.property('a').isException());
  // b has setter but no getter.
-assertTrue(mirror.property('b').value() instanceof debug.AccessorMirror);
+assertFalse(mirror.property('b').hasGetter());
+assertTrue(mirror.property('b').hasSetter());
  assertEquals(debug.PropertyType.Callbacks,  
mirror.property('b').propertyType());
-// c has both getter and setter.
-assertTrue(mirror.property('c').value() instanceof debug.AccessorMirror);
+assertEquals('undefined', mirror.property('b').getter().type());
+assertEquals('function', mirror.property('b').setter().type());
+assertEquals('function (){}', mirror.property('b').setter().source());
+assertFalse(mirror.property('b').isException());
+// c has both getter and setter. The getter throws an exception.
+assertTrue(mirror.property('c').hasGetter());
+assertTrue(mirror.property('c').hasSetter());
  assertEquals(debug.PropertyType.Callbacks,  
mirror.property('c').propertyType());
+assertEquals('function', mirror.property('c').getter().type());
+assertEquals('function', mirror.property('c').setter().type());
+assertEquals('function (){throw \'c\';}',  
mirror.property('c').getter().source());
+assertEquals('function (){throw \'c\';}',  
mirror.property('c').setter().source());
+assertEquals('c', mirror.property('c').value().value());
+assertTrue(mirror.property('c').isException());

  // Test objects with native accessors.
  mirror = debug.MakeMirror(new String('abc'));
  assertTrue(mirror instanceof debug.ObjectMirror);
-assertTrue(mirror.property('length').value() instanceof  
debug.AccessorMirror);
-assertTrue(mirror.property('length').value().isNative());
+assertFalse(mirror.property('length').hasGetter());
+assertFalse(mirror.property('length').hasSetter());
+assertTrue(mirror.property('length').isNative());
  assertEquals('a', mirror.property(0).value().value());
  assertEquals('b', mirror.property(1).value().value());
  assertEquals('c', mirror.property(2).value().value());

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to