Commit 4783d3c3 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Remove 'type' and 'arguments' properties from Error object.

R=svenpanne@chromium.org
BUG=v8:2397

Review URL: https://chromiumcodereview.appspot.com/11358214

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12956 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8a210a78
......@@ -252,13 +252,8 @@ function ToDetailString(obj) {
function MakeGenericError(constructor, type, args) {
if (IS_UNDEFINED(args)) {
args = [];
}
var e = new constructor(FormatMessage(type, args));
e.type = type;
e.arguments = args;
return e;
if (IS_UNDEFINED(args)) args = [];
return new constructor(FormatMessage(type, args));
}
......@@ -1143,8 +1138,6 @@ function SetUpError() {
// object. This avoids going through getters and setters defined
// on prototype objects.
%IgnoreAttributesAndSetProperty(this, 'stack', void 0, DONT_ENUM);
%IgnoreAttributesAndSetProperty(this, 'arguments', void 0, DONT_ENUM);
%IgnoreAttributesAndSetProperty(this, 'type', void 0, DONT_ENUM);
if (!IS_UNDEFINED(m)) {
%IgnoreAttributesAndSetProperty(
this, 'message', ToString(m), DONT_ENUM);
......@@ -1204,7 +1197,6 @@ function GetPropertyWithoutInvokingMonkeyGetters(error, name) {
function ErrorToStringDetectCycle(error) {
if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker;
try {
var type = GetPropertyWithoutInvokingMonkeyGetters(error, "type");
var name = GetPropertyWithoutInvokingMonkeyGetters(error, "name");
name = IS_UNDEFINED(name) ? "Error" : TO_STRING_INLINE(name);
var message = GetPropertyWithoutInvokingMonkeyGetters(error, "message");
......
......@@ -1041,6 +1041,31 @@ TEST(ScopePositions) {
}
i::Handle<i::String> FormatMessage(i::ScriptDataImpl* data) {
i::Handle<i::String> format = v8::Utils::OpenHandle(
*v8::String::New(data->BuildMessage()));
i::Vector<const char*> args = data->BuildArgs();
i::Handle<i::JSArray> args_array = FACTORY->NewJSArray(args.length());
for (int i = 0; i < args.length(); i++) {
i::JSArray::SetElement(args_array,
i,
v8::Utils::OpenHandle(*v8::String::New(args[i])),
NONE,
i::kNonStrictMode);
}
i::Handle<i::JSObject> builtins(i::Isolate::Current()->js_builtins_object());
i::Handle<i::Object> format_fun =
i::GetProperty(builtins, "FormatMessage");
i::Handle<i::Object> arg_handles[] = { format, args_array };
bool has_exception = false;
i::Handle<i::Object> result =
i::Execution::Call(format_fun, builtins, 2, arg_handles, &has_exception);
CHECK(!has_exception);
CHECK(result->IsString());
return i::Handle<i::String>::cast(result);
}
void TestParserSync(i::Handle<i::String> source, int flags) {
uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
bool harmony_scoping = ((i::kLanguageModeMask & flags) == i::EXTENDED_MODE);
......@@ -1067,53 +1092,50 @@ void TestParserSync(i::Handle<i::String> source, int flags) {
i::FunctionLiteral* function = parser.ParseProgram();
i::FLAG_harmony_scoping = save_harmony_scoping;
i::String* type_string = NULL;
// Check that preparsing fails iff parsing fails.
if (function == NULL) {
// Extract exception from the parser.
i::Handle<i::String> type_symbol = FACTORY->LookupAsciiSymbol("type");
CHECK(i::Isolate::Current()->has_pending_exception());
i::MaybeObject* maybe_object = i::Isolate::Current()->pending_exception();
i::JSObject* exception = NULL;
CHECK(maybe_object->To(&exception));
i::Handle<i::JSObject> exception_handle(exception);
i::Handle<i::String> message_string =
i::GetProperty(exception_handle, "message");
// Get the type string.
maybe_object = exception->GetProperty(*type_symbol);
CHECK(maybe_object->To(&type_string));
}
// Check that preparsing fails iff parsing fails.
if (data.has_error() && function != NULL) {
i::OS::Print(
"Preparser failed on:\n"
"\t%s\n"
"with error:\n"
"\t%s\n"
"However, the parser succeeded",
*source->ToCString(), data.BuildMessage());
CHECK(false);
} else if (!data.has_error() && function == NULL) {
i::OS::Print(
"Parser failed on:\n"
"\t%s\n"
"with error:\n"
"\t%s\n"
"However, the preparser succeeded",
*source->ToCString(), *type_string->ToCString());
CHECK(false);
}
// Check that preparser and parser produce the same error.
if (function == NULL) {
if (!type_string->IsEqualTo(i::CStrVector(data.BuildMessage()))) {
if (!data.has_error()) {
i::OS::Print(
"Parser failed on:\n"
"\t%s\n"
"with error:\n"
"\t%s\n"
"However, the preparser succeeded",
*source->ToCString(), *message_string->ToCString());
CHECK(false);
}
// Check that preparser and parser produce the same error.
i::Handle<i::String> preparser_message = FormatMessage(&data);
if (!message_string->Equals(*preparser_message)) {
i::OS::Print(
"Expected parser and preparser to produce the same error on:\n"
"\t%s\n"
"However, found the following error messages\n"
"\tparser: %s\n"
"\tpreparser: %s\n",
*source->ToCString(), *type_string->ToCString(), data.BuildMessage());
*source->ToCString(),
*message_string->ToCString(),
*preparser_message->ToCString());
CHECK(false);
}
} else if (data.has_error()) {
i::OS::Print(
"Preparser failed on:\n"
"\t%s\n"
"with error:\n"
"\t%s\n"
"However, the parser succeeded",
*source->ToCString(), *FormatMessage(&data)->ToCString());
CHECK(false);
}
}
......
......@@ -418,8 +418,8 @@ try {
exception = true;
assertTrue(e instanceof TypeError,
"reduce callback not a function not throwing TypeError");
assertEquals("called_non_callable", e.type,
"reduce non function TypeError type");
assertTrue(e.message.indexOf(" is not a function") >= 0,
"reduce non function TypeError type");
}
assertTrue(exception);
......@@ -430,8 +430,8 @@ try {
exception = true;
assertTrue(e instanceof TypeError,
"reduceRight callback not a function not throwing TypeError");
assertEquals("called_non_callable", e.type,
"reduceRight non function TypeError type");
assertTrue(e.message.indexOf(" is not a function") >= 0,
"reduceRight non function TypeError type");
}
assertTrue(exception);
......@@ -442,7 +442,7 @@ try {
exception = true;
assertTrue(e instanceof TypeError,
"reduce no initial value not throwing TypeError");
assertEquals("reduce_no_initial", e.type,
assertEquals("Reduce of empty array with no initial value", e.message,
"reduce no initial TypeError type");
}
assertTrue(exception);
......@@ -454,7 +454,7 @@ try {
exception = true;
assertTrue(e instanceof TypeError,
"reduceRight no initial value not throwing TypeError");
assertEquals("reduce_no_initial", e.type,
assertEquals("Reduce of empty array with no initial value", e.message,
"reduceRight no initial TypeError type");
}
assertTrue(exception);
......@@ -466,7 +466,7 @@ try {
exception = true;
assertTrue(e instanceof TypeError,
"reduce sparse no initial value not throwing TypeError");
assertEquals("reduce_no_initial", e.type,
assertEquals("Reduce of empty array with no initial value", e.message,
"reduce no initial TypeError type");
}
assertTrue(exception);
......@@ -478,7 +478,7 @@ try {
exception = true;
assertTrue(e instanceof TypeError,
"reduceRight sparse no initial value not throwing TypeError");
assertEquals("reduce_no_initial", e.type,
assertEquals("Reduce of empty array with no initial value", e.message,
"reduceRight no initial TypeError type");
}
assertTrue(exception);
......
......@@ -36,10 +36,6 @@ assertFalse(desc['enumerable']);
var e = new Error("foobar");
desc = Object.getOwnPropertyDescriptor(e, 'message');
assertFalse(desc['enumerable']);
desc = Object.getOwnPropertyDescriptor(e, 'arguments');
assertFalse(desc['enumerable']);
desc = Object.getOwnPropertyDescriptor(e, 'type');
assertFalse(desc['enumerable']);
desc = Object.getOwnPropertyDescriptor(e, 'stack');
assertFalse(desc['enumerable']);
......@@ -57,26 +53,17 @@ for (var v in e) {
function fail() { assertUnreachable(); };
ReferenceError.prototype.__defineSetter__('name', fail);
ReferenceError.prototype.__defineSetter__('message', fail);
ReferenceError.prototype.__defineSetter__('type', fail);
ReferenceError.prototype.__defineSetter__('arguments', fail);
ReferenceError.prototype.__defineSetter__('stack', fail);
var e = new ReferenceError();
assertTrue(e.hasOwnProperty('stack'));
assertTrue(e.hasOwnProperty('type'));
assertTrue(e.hasOwnProperty('arguments'));
var e = new ReferenceError('123');
assertTrue(e.hasOwnProperty('message'));
assertTrue(e.hasOwnProperty('stack'));
assertTrue(e.hasOwnProperty('type'));
assertTrue(e.hasOwnProperty('arguments'));
var e = %MakeReferenceError("my_test_error", [0, 1]);
assertTrue(e.hasOwnProperty('stack'));
assertTrue(e.hasOwnProperty('type'));
assertTrue(e.hasOwnProperty('arguments'));
assertEquals("my_test_error", e.type)
// Check that intercepting property access from toString is prevented for
// compiler errors. This is not specified, but allowing interception
......@@ -86,7 +73,7 @@ var errors = [SyntaxError, ReferenceError, TypeError];
for (var i in errors) {
var name = errors[i].prototype.toString();
// Monkey-patch prototype.
var props = ["name", "message", "type", "arguments", "stack"];
var props = ["name", "message", "stack"];
for (var j in props) {
errors[i].prototype.__defineGetter__(props[j], fail);
}
......
......@@ -150,6 +150,11 @@ var reducing_functions =
[Array.prototype.reduce,
Array.prototype.reduceRight];
function checkExpectedMessage(e) {
assertTrue(e.message.indexOf("called on null or undefined") >= 0 ||
e.message.indexOf("Cannot convert null to object") >= 0);
}
// Test that all natives using the ToObject call throw the right exception.
for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
// Sanity check that all functions are correct
......@@ -166,8 +171,7 @@ for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
should_throw_on_null_and_undefined[i].call(null);
} catch (e) {
exception = true;
assertTrue("called_on_null_or_undefined" == e.type ||
"null_to_object" == e.type);
checkExpectedMessage(e);
}
assertTrue(exception);
......@@ -176,8 +180,7 @@ for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
should_throw_on_null_and_undefined[i].call(undefined);
} catch (e) {
exception = true;
assertTrue("called_on_null_or_undefined" == e.type ||
"null_to_object" == e.type);
checkExpectedMessage(e);
}
assertTrue(exception);
......@@ -186,8 +189,7 @@ for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
should_throw_on_null_and_undefined[i].apply(null);
} catch (e) {
exception = true;
assertTrue("called_on_null_or_undefined" == e.type ||
"null_to_object" == e.type);
checkExpectedMessage(e);
}
assertTrue(exception);
......@@ -196,8 +198,7 @@ for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
should_throw_on_null_and_undefined[i].apply(undefined);
} catch (e) {
exception = true;
assertTrue("called_on_null_or_undefined" == e.type ||
"null_to_object" == e.type);
checkExpectedMessage(e);
}
assertTrue(exception);
}
......@@ -257,8 +258,7 @@ for (var j = 0; j < mapping_functions.length; j++) {
null);
} catch (e) {
exception = true;
assertTrue("called_on_null_or_undefined" == e.type ||
"null_to_object" == e.type);
checkExpectedMessage(e);
}
assertTrue(exception);
......@@ -269,8 +269,7 @@ for (var j = 0; j < mapping_functions.length; j++) {
undefined);
} catch (e) {
exception = true;
assertTrue("called_on_null_or_undefined" == e.type ||
"null_to_object" == e.type);
checkExpectedMessage(e);
}
assertTrue(exception);
}
......@@ -311,8 +310,7 @@ for (var j = 0; j < reducing_functions.length; j++) {
reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
} catch (e) {
exception = true;
assertTrue("called_on_null_or_undefined" == e.type ||
"null_to_object" == e.type);
checkExpectedMessage(e);
}
assertTrue(exception);
......@@ -321,8 +319,7 @@ for (var j = 0; j < reducing_functions.length; j++) {
reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
} catch (e) {
exception = true;
assertTrue("called_on_null_or_undefined" == e.type ||
"null_to_object" == e.type);
checkExpectedMessage(e);
}
assertTrue(exception);
}
......
......@@ -34,7 +34,7 @@ for (var i = 0; i < invalid_this.length; i++) {
Error.prototype.toString.call(invalid_this[i]);
} catch (e) {
exception = true;
assertTrue("called_on_non_object" == e.type);
assertEquals("Error.prototype.toString called on non-object", e.message);
}
assertTrue(exception);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment