Make formatting error message side-effect-free.
BUG=v8:2398 Review URL: https://chromiumcodereview.appspot.com/11359130 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12926 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ef1b3d3a76
commit
4cca6c6081
@ -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,
|
||||
|
@ -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
|
||||
|
@ -4238,6 +4238,33 @@ 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.IsFound()) 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();
|
||||
case CALLBACKS:
|
||||
case HANDLER:
|
||||
case INTERCEPTOR:
|
||||
case TRANSITION:
|
||||
return isolate->heap()->undefined_value();
|
||||
case NONEXISTENT:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
|
||||
Handle<Object> object,
|
||||
Handle<Object> key,
|
||||
|
@ -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) \
|
||||
|
41
test/mjsunit/regress/regress-2398.js
Normal file
41
test/mjsunit/regress/regress-2398.js
Normal file
@ -0,0 +1,41 @@
|
||||
// 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:
|
||||
//
|
||||
// * 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.
|
||||
|
||||
"use strict";
|
||||
|
||||
var observed = false;
|
||||
|
||||
var object = { get toString() { observed = true; } };
|
||||
Object.defineProperty(object, "ro", { value: 1 });
|
||||
|
||||
try {
|
||||
object.ro = 2; // TypeError caused by trying to write to read-only.
|
||||
} catch (e) {
|
||||
e.message; // Forces formatting of the message object.
|
||||
}
|
||||
|
||||
assertFalse(observed);
|
Loading…
Reference in New Issue
Block a user