Reviewers: Sven Panne,
Message:
PTAL.
Description:
Make formatting error message side-effect-free.
BUG=v8:2398
Please review this at http://codereview.chromium.org/11359130/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/isolate.cc
M src/messages.js
M src/runtime.h
M src/runtime.cc
A + test/mjsunit/regress/regress-2398.js
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index
75e15a454196573fce28a438032a7fe68e966ddb..b077a70f6b90aa1ae679c9802f8ed8faeb343622
100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1138,6 +1138,14 @@ void Isolate::DoThrow(Object* exception,
MessageLocation* location) {
stack_trace_for_uncaught_exceptions_options_);
}
}
+ // Stringify custom error objects for the message object.
+ if (exception_handle->IsJSObject()
&& !IsErrorObject(exception_handle)) {
+ bool failed = false;
+ exception_handle = Execution::ToString(exception_handle, &failed);
+ if (failed) {
+ exception_handle = factory()->LookupAsciiSymbol("exception");
+ }
+ }
Handle<Object> message_obj = MessageHandler::MakeMessageObject(
"uncaught_exception",
location,
Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index
58f0db09f3741f68213139f446284ad951861b7a..f04bed962d604bc45adaba1f0aec89c6240a6ec7
100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -167,7 +167,7 @@ function FormatString(format, args) {
if (arg_num < 4) {
// str is one of %0, %1, %2 or %3.
try {
- str = ToDetailString(args[arg_num]);
+ str = NoSideEffectToString(args[arg_num]);
} catch (e) {
if (%IsJSModule(args[arg_num]))
str = "module";
@@ -184,6 +184,26 @@ function FormatString(format, args) {
}
+function NoSideEffectToString(obj) {
+ if (IS_STRING(obj)) return obj;
+ if (IS_NUMBER(obj)) return %_NumberToString(obj);
+ if (IS_BOOLEAN(obj)) return x ? 'true' : 'false';
+ if (IS_UNDEFINED(obj)) return 'undefined';
+ if (IS_NULL(obj)) return 'null';
+ if (IS_OBJECT(obj) && %GetDataProperty(obj, "toString") ===
ObjectToString) {
+ var constructor = obj.constructor;
+ if (typeof constructor == "function") {
+ var constructorName = constructor.name;
+ if (IS_STRING(constructorName) && constructorName !== "") {
+ return "#<" + constructorName + ">";
+ }
+ }
+ }
+ if (IsNativeErrorObject(obj)) return %_CallFunction(obj, ErrorToString);
+ return %_CallFunction(obj, ObjectToString);
+}
+
+
// To check if something is a native error we need to check the
// concrete native error types. It is not sufficient to use instanceof
// since it possible to create an object that has Error.prototype on
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
fb40d5e73e3c3dd85b15165c88487f6d893cbd5f..3129c930a2e2fcc751271f59865e2c81186f301c
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -4238,6 +4238,27 @@ RUNTIME_FUNCTION(MaybeObject*,
Runtime_DefineOrRedefineDataProperty) {
}
+// Return property without being observable by accessors or interceptors.
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
+ LookupResult lookup(isolate);
+ object->LookupRealNamedProperty(*key, &lookup);
+ if (!lookup.IsProperty()) return isolate->heap()->undefined_value();
+ switch (lookup.type()) {
+ case NORMAL:
+ return lookup.holder()->GetNormalizedProperty(&lookup);
+ case FIELD:
+ return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
+ case CONSTANT_FUNCTION:
+ return lookup.GetConstantFunction();
+ default:
+ return isolate->heap()->undefined_value();
+ }
+}
+
+
MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
Handle<Object> object,
Handle<Object> key,
Index: src/runtime.h
diff --git a/src/runtime.h b/src/runtime.h
index
4f8d1d77c3d62472f3bcc5d12d16fc12934424eb..f63844c7b1af6727c5e99b4fa4d573410564e7da
100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -267,6 +267,7 @@ namespace internal {
F(DefineOrRedefineDataProperty, 4, 1) \
F(DefineOrRedefineAccessorProperty, 5, 1) \
F(IgnoreAttributesAndSetProperty, -1 /* 3 or 4 */, 1) \
+ F(GetDataProperty, 2, 1) \
\
/* Arrays */ \
F(RemoveArrayHoles, 2, 1) \
Index: test/mjsunit/regress/regress-2398.js
diff --git a/test/mjsunit/regress/regress-136048.js
b/test/mjsunit/regress/regress-2398.js
similarity index 84%
copy from test/mjsunit/regress/regress-136048.js
copy to test/mjsunit/regress/regress-2398.js
index
c9972e96fc062b4618f8bf40ee83c15f185ff17c..1c66e7f84c041695c2718ce655fbe47ae38b1866
100644
--- a/test/mjsunit/regress/regress-136048.js
+++ b/test/mjsunit/regress/regress-2398.js
@@ -25,10 +25,17 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"use strict";
+
+var observed = false;
+
+var object = { get toString() { observed = true; } };
+Object.defineProperty(object, "ro", { value: 1 });
+
try {
- /foo/\u0069
+ object.ro = 2; // TypeError caused by trying to write to read-only.
} catch (e) {
- assertEquals(
- "SyntaxError: Invalid flags supplied to RegExp
constructor '\\u0069'",
- e.toString());
+ e.message; // Forces formatting of the message object.
}
+
+assertFalse(observed);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev