Revision: 9790
Author: [email protected]
Date: Wed Oct 26 03:41:52 2011
Log: Fix Error.prototype.toString to be ES5 conform.
[email protected]
TEST=test262/15.11.4.4-8-1,mjsunit/error-tostring
Review URL: http://codereview.chromium.org/8341021
http://code.google.com/p/v8/source/detail?r=9790
Added:
/branches/bleeding_edge/test/mjsunit/error-tostring.js
Deleted:
/branches/bleeding_edge/test/mjsunit/cyclic-error-to-string.js
Modified:
/branches/bleeding_edge/src/messages.js
/branches/bleeding_edge/src/mirror-debugger.js
/branches/bleeding_edge/test/test262/test262.status
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/error-tostring.js Wed Oct 26
03:41:52 2011
@@ -0,0 +1,85 @@
+// Copyright 2011 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:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// Test default string representation of an Error object.
+
+var e = new Error();
+assertEquals('Error', e.toString());
+
+
+// Test printing of cyclic errors which return the empty string for
+// compatibility with Safari and Firefox.
+
+e = new Error();
+e.name = e;
+e.message = e;
+e.stack = "Does not occur in output";
+e.arguments = "Does not occur in output";
+e.type = "Does not occur in output";
+assertEquals('', e.toString());
+
+e = new Error();
+e.name = [ e ];
+e.message = [ e ];
+e.stack = "Does not occur in output";
+e.arguments = "Does not occur in output";
+e.type = "Does not occur in output";
+assertEquals('', e.toString());
+
+
+// Test the sequence in which getters and toString operations are called
+// on a given Error object. Verify the produced string representation.
+
+function testErrorToString(nameValue, messageValue) {
+ var seq = [];
+ var e = {
+ get name() {
+ seq.push(1);
+ return (nameValue === undefined) ? nameValue : {
+ toString: function() { seq.push(2); return nameValue; }
+ };
+ },
+ get message() {
+ seq.push(3);
+ return (messageValue === undefined) ? messageValue : {
+ toString: function() { seq.push(4); return messageValue; }
+ };
+ }
+ };
+ var string = Error.prototype.toString.call(e);
+ return [string,seq];
+}
+
+assertEquals(["Error",[1,3]], testErrorToString(undefined, undefined));
+assertEquals(["e1",[1,2,3]], testErrorToString("e1", undefined));
+assertEquals(["e1: null",[1,2,3,4]], testErrorToString("e1", null));
+assertEquals(["e1",[1,2,3,4]], testErrorToString("e1", ""));
+assertEquals(["Error: e2",[1,3,4]], testErrorToString(undefined, "e2"));
+assertEquals(["null: e2",[1,2,3,4]], testErrorToString(null, "e2"));
+assertEquals(["e2",[1,2,3,4]], testErrorToString("", "e2"));
+assertEquals(["e1: e2",[1,2,3,4]], testErrorToString("e1", "e2"));
=======================================
--- /branches/bleeding_edge/test/mjsunit/cyclic-error-to-string.js Fri Jan
21 06:11:35 2011
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2011 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
-
-var e = new Error();
-assertEquals('Error', e + '');
-
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
-
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
=======================================
--- /branches/bleeding_edge/src/messages.js Tue Oct 25 01:33:08 2011
+++ /branches/bleeding_edge/src/messages.js Wed Oct 26 03:41:52 2011
@@ -83,7 +83,7 @@
// objects between script tags in a browser setting.
function ToStringCheckErrorObject(obj) {
if (IsNativeErrorObject(obj)) {
- return %_CallFunction(obj, errorToString);
+ return %_CallFunction(obj, ErrorToString);
} else {
return ToString(obj);
}
@@ -1146,42 +1146,43 @@
%SetProperty($Error.prototype, 'message', '', DONT_ENUM);
-// Global list of error objects visited during errorToString. This is
+// Global list of error objects visited during ErrorToString. This is
// used to detect cycles in error toString formatting.
const visited_errors = new InternalArray();
const cyclic_error_marker = new $Object();
-function errorToStringDetectCycle(error) {
+function ErrorToStringDetectCycle(error) {
if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker;
try {
var type = error.type;
+ var name = error.name
+ name = IS_UNDEFINED(name) ? "Error" : TO_STRING_INLINE(name);
+ var message = error.message;
var hasMessage = %_CallFunction(error, "message",
ObjectHasOwnProperty);
if (type && !hasMessage) {
- var formatted = FormatMessage(%NewMessageObject(type,
error.arguments));
- return error.name + ": " + formatted;
- }
- var message = hasMessage ? (": " + error.message) : "";
- return error.name + message;
+ message = FormatMessage(%NewMessageObject(type, error.arguments));
+ }
+ message = IS_UNDEFINED(message) ? "" : TO_STRING_INLINE(message);
+ if (name === "") return message;
+ if (message === "") return name;
+ return name + ": " + message;
} finally {
visited_errors.length = visited_errors.length - 1;
}
}
-function errorToString() {
+function ErrorToString() {
if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
throw MakeTypeError("called_on_null_or_undefined",
["Error.prototype.toString"]);
}
- // This helper function is needed because access to properties on
- // the builtins object do not work inside of a catch clause.
- function isCyclicErrorMarker(o) { return o === cyclic_error_marker; }
try {
- return errorToStringDetectCycle(this);
+ return ErrorToStringDetectCycle(this);
} catch(e) {
// If this error message was encountered already return the empty
// string for it instead of recursively formatting it.
- if (isCyclicErrorMarker(e)) {
+ if (e === cyclic_error_marker) {
return '';
}
throw e;
@@ -1189,7 +1190,7 @@
}
-InstallFunctions($Error.prototype, DONT_ENUM, ['toString', errorToString]);
+InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]);
// Boilerplate for exceptions for stack overflows. Used from
// Isolate::StackOverflow().
=======================================
--- /branches/bleeding_edge/src/mirror-debugger.js Mon Sep 19 11:36:47 2011
+++ /branches/bleeding_edge/src/mirror-debugger.js Wed Oct 26 03:41:52 2011
@@ -1087,7 +1087,7 @@
// Use the same text representation as in messages.js.
var text;
try {
- str = %_CallFunction(this.value_, builtins.errorToString);
+ str = %_CallFunction(this.value_, builtins.ErrorToString);
} catch (e) {
str = '#<Error>';
}
=======================================
--- /branches/bleeding_edge/test/test262/test262.status Wed Oct 19 06:56:18
2011
+++ /branches/bleeding_edge/test/test262/test262.status Wed Oct 26 03:41:52
2011
@@ -502,9 +502,6 @@
# Bug? Date.prototype.toISOString - value of year is Infinity
# Date.prototype.toISOString throw the RangeError
15.9.5.43-0-15: FAIL
-# Bug? Error.prototype.toString return the value of 'msg' when 'name' is
empty
-# string and 'msg' isn't undefined
-15.11.4.4-8-1: FAIL
############################ SKIPPED TESTS #############################
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev