Index: src/api.cc |
diff --git a/src/api.cc b/src/api.cc |
index 0c78b5f27058f923fc02ccd2b9b6dc6e53c8bca7..512593014ec3b8bf74ead50ad125abe72f3d85ab 100644 |
--- a/src/api.cc |
+++ b/src/api.cc |
@@ -46,6 +46,7 @@ |
#include "src/snapshot.h" |
#include "src/unicode-inl.h" |
#include "src/v8threads.h" |
+#include "src/vector.h" |
#include "src/version.h" |
#include "src/vm-state-inl.h" |
@@ -3379,6 +3380,7 @@ Local<String> v8::Object::ObjectProtoToString() { |
i::Handle<i::JSObject> self = Utils::OpenHandle(this); |
i::Handle<i::Object> name(self->class_name(), i_isolate); |
+ i::Handle<i::Object> tag; |
// Native implementation of Object.prototype.toString (v8natives.js): |
// var c = %_ClassOf(this); |
@@ -3393,6 +3395,44 @@ Local<String> v8::Object::ObjectProtoToString() { |
i_isolate->factory()->Arguments_string())) { |
return v8::String::NewFromUtf8(isolate, "[object Object]"); |
} else { |
+ if (internal::FLAG_harmony_tostring) { |
+ i::Handle<i::Symbol> toStringTag = Utils::OpenHandle( |
+ *Symbol::GetToStringTag(isolate)); |
+ tag = i::Runtime::GetObjectProperty( |
+ i_isolate, self, toStringTag).ToHandleChecked(); |
+ |
+ if (!tag->IsUndefined()) { |
+ if (!tag->IsString()) { |
+ return v8::String::NewFromUtf8(isolate, "[object ???]"); |
+ } else { |
+ i::Handle<i::String> tag_name = i::Handle<i::String>::cast(tag); |
+ using namespace internal; |
+ if (!i::String::Equals(class_name, tag_name)) { |
+ if (tag_name->IsUtf8EqualTo(CStrVector("Arguments"))) { |
+ return v8::String::NewFromUtf8(isolate, "[object ~Arguments]"); |
caitp (gmail)
2014/10/17 22:00:49
I'm not sure if it's worth doing this linearly, or
Dmitry Lomov (no reviews)
2014/10/18 08:41:49
Instead of IsUtf8EqualTo with a new string constan
|
+ } else if (tag_name->IsUtf8EqualTo(CStrVector("Array"))) { |
+ return v8::String::NewFromUtf8(isolate, "[object ~Array]"); |
+ } else if (tag_name->IsUtf8EqualTo(CStrVector("Boolean"))) { |
+ return v8::String::NewFromUtf8(isolate, "[object ~Boolean]"); |
+ } else if (tag_name->IsUtf8EqualTo(CStrVector("Date"))) { |
+ return v8::String::NewFromUtf8(isolate, "[object ~Date]"); |
+ } else if (tag_name->IsUtf8EqualTo(CStrVector("Error"))) { |
+ return v8::String::NewFromUtf8(isolate, "[object ~Error]"); |
+ } else if (tag_name->IsUtf8EqualTo(CStrVector("Function"))) { |
+ return v8::String::NewFromUtf8(isolate, "[object ~Function]"); |
+ } else if (tag_name->IsUtf8EqualTo(CStrVector("Number"))) { |
+ return v8::String::NewFromUtf8(isolate, "[object ~Number]"); |
+ } else if (tag_name->IsUtf8EqualTo(CStrVector("RegExp"))) { |
+ return v8::String::NewFromUtf8(isolate, "[object ~RegExp]"); |
+ } else if (tag_name->IsUtf8EqualTo(CStrVector("String"))) { |
+ return v8::String::NewFromUtf8(isolate, "[object ~String]"); |
+ } else { |
+ class_name = tag_name; |
+ } |
+ } |
+ } |
+ } |
+ } |
const char* prefix = "[object "; |
Local<String> str = Utils::ToLocal(class_name); |
const char* postfix = "]"; |
@@ -6199,6 +6239,11 @@ Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) { |
} |
+Local<Symbol> v8::Symbol::GetToStringTag(Isolate* isolate) { |
+ return GetWellKnownSymbol(isolate, "Symbol.toStringTag"); |
+} |
+ |
+ |
Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) { |
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
LOG_API(i_isolate, "Private::New()"); |