Reviewers: Mads Ager,

Description:
Added .message accessor to messages.  This gives you the same
descriptive message as is used to construct the toString() for an
error object.

Please review this at http://codereview.chromium.org/40293

Affected files:
   M src/messages.js


Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index  
d5adbc931430b755112f7daecc275da9df7e7b47..6ef97504d828627f7051e254c4b1b6c02673a2b0
  
100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -153,7 +153,7 @@ function MakeGenericError(constructor, type, args) {
      args = [];
    }

-  var e = new constructor();
+  var e = new constructor(kAddMessageAccessorsMarker);
    e.type = type;
    e.arguments = args;
    return e;
@@ -589,6 +589,29 @@ function UnsafeGetStackTraceLine(recv, fun, pos,  
isTopLevel) {
  //  
----------------------------------------------------------------------------
  // Error implementation

+// If this object gets passed to an error constructor the error will
+// get an accessor for .message that constructs a descriptive error
+// message on access.
+var kAddMessageAccessorsMarker = { };
+
+// Defines accessors for a property that is calculated the first time
+// the property is read and then replaces the accessor with the value.
+// Also, setting the property causes the accessors to be deleted.
+function DefineOneShotAccessor(obj, name, fun) {
+  // Note that the accessors consistently operate on 'obj', not 'this'.
+  // Since the object may occur in someone else's prototype chain we
+  // can't rely on 'this' being the same as 'obj'.
+  obj.__defineGetter__(name, function () {
+    var value = fun(obj);
+    obj[name] = value;
+    return value;
+  });
+  obj.__defineSetter__(name, function (v) {
+    delete obj[name];
+    obj[name] = v;
+  });
+}
+
  function DefineError(f) {
    // Store the error function in both the global object
    // and the runtime object. The function is fetched
@@ -607,7 +630,13 @@ function DefineError(f) {
    f.prototype.name = name;
    %SetCode(f, function(m) {
      if (%IsConstructCall()) {
-      if (!IS_UNDEFINED(m)) this.message = ToString(m);
+      if (m === kAddMessageAccessorsMarker) {
+        DefineOneShotAccessor(this, 'message', function (obj) {
+          return FormatMessage({type: obj.type, args: obj.arguments});
+        });
+      } else if (!IS_UNDEFINED(m)) {
+        this.message = ToString(m);
+      }
      } else {
        return new f(m);
      }



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

Reply via email to