Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Unified Diff: src/messages.cc

Issue 1281833002: Rewrite Error.prototype.toString in C++. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix test case Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/messages.h ('k') | src/messages.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/messages.cc
diff --git a/src/messages.cc b/src/messages.cc
index 55edfa89c45f96198c3d4df3dfa3499321a6a9b3..306fcc503f4ff4d34e75823bc6ced8246e7fd89d 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -367,5 +367,97 @@ MaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
return builder.Finish();
}
+
+
+MaybeHandle<String> ErrorToStringHelper::Stringify(Isolate* isolate,
+ Handle<JSObject> error) {
+ VisitedScope scope(this, error);
+ if (scope.has_visited()) return isolate->factory()->empty_string();
+
+ Handle<String> name;
+ Handle<String> message;
+ Handle<Name> internal_key = isolate->factory()->internal_error_symbol();
+ Handle<String> message_string =
+ isolate->factory()->NewStringFromStaticChars("message");
+ Handle<String> name_string = isolate->factory()->name_string();
+ LookupIterator internal_error_lookup(
+ error, internal_key, LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
+ LookupIterator message_lookup(
+ error, message_string, LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
+ LookupIterator name_lookup(error, name_string,
+ LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
+
+ // Find out whether an internally created error object is on the prototype
+ // chain. If the name property is found on a holder prior to the internally
+ // created error object, use that name property. Otherwise just use the
+ // constructor name to avoid triggering possible side effects.
+ // Similar for the message property. If the message property shadows the
+ // internally created error object, use that message property. Otherwise
+ // use empty string as message.
+ if (internal_error_lookup.IsFound()) {
+ if (!ShadowsInternalError(isolate, &name_lookup, &internal_error_lookup)) {
+ Handle<JSObject> holder = internal_error_lookup.GetHolder<JSObject>();
+ name = Handle<String>(holder->constructor_name());
+ }
+ if (!ShadowsInternalError(isolate, &message_lookup,
+ &internal_error_lookup)) {
+ message = isolate->factory()->empty_string();
+ }
+ }
+ if (name.is_null()) {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, name,
+ GetStringifiedProperty(isolate, &name_lookup,
+ isolate->factory()->Error_string()),
+ String);
+ }
+ if (message.is_null()) {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, message,
+ GetStringifiedProperty(isolate, &message_lookup,
+ isolate->factory()->empty_string()),
+ String);
+ }
+
+ if (name->length() == 0) return message;
+ if (message->length() == 0) return name;
+ IncrementalStringBuilder builder(isolate);
+ builder.AppendString(name);
+ builder.AppendCString(": ");
+ builder.AppendString(message);
+ return builder.Finish();
+}
+
+
+bool ErrorToStringHelper::ShadowsInternalError(
+ Isolate* isolate, LookupIterator* property_lookup,
+ LookupIterator* internal_error_lookup) {
+ Handle<JSObject> holder = property_lookup->GetHolder<JSObject>();
+ // It's fine if the property is defined on the error itself.
+ if (holder.is_identical_to(property_lookup->GetReceiver())) return true;
+ PrototypeIterator it(isolate, holder, PrototypeIterator::START_AT_RECEIVER);
+ while (true) {
+ if (it.IsAtEnd()) return false;
+ if (it.IsAtEnd(internal_error_lookup->GetHolder<JSObject>())) return true;
+ it.AdvanceIgnoringProxies();
+ }
+}
+
+
+MaybeHandle<String> ErrorToStringHelper::GetStringifiedProperty(
+ Isolate* isolate, LookupIterator* property_lookup,
+ Handle<String> default_value) {
+ if (!property_lookup->IsFound()) return default_value;
+ Handle<Object> obj;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Object::GetProperty(property_lookup),
+ String);
+ if (obj->IsUndefined()) return default_value;
+ if (!obj->IsString()) {
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, Execution::ToString(isolate, obj),
+ String);
+ }
+ return Handle<String>::cast(obj);
+}
+
} // namespace internal
} // namespace v8
« no previous file with comments | « src/messages.h ('k') | src/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698