Commit f723b123 authored by neis's avatar neis Committed by Commit bot

[proxies] Recognize arraylike proxies in Object.prototype.toString.

We must print "[object Array]" for proxies that satisfy Array.isArray.

Cosmetic change on the side: move ObjectProtoToString from JSObject to Object
since it deals with arbitrary objects.

R=adamk@chromium.org, verwaest@chromium.org
BUG=v8:1543
LOG=n

Review URL: https://codereview.chromium.org/1526023002

Cr-Commit-Position: refs/heads/master@{#32902}
parent 01662f1b
// Copyright 2013 the V8 project authors. All rights reserved.
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -2333,6 +2333,18 @@ String* JSReceiver::class_name() {
}
MaybeHandle<String> JSReceiver::BuiltinStringTag(Handle<JSReceiver> object) {
Maybe<bool> is_array = Object::IsArray(object);
MAYBE_RETURN(is_array, MaybeHandle<String>());
if (is_array.FromJust()) {
return object->GetIsolate()->factory()->Array_string();
}
// TODO(adamk): class_name() is expensive, replace with instance type
// checks where possible.
return handle(object->class_name());
}
// static
Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
Isolate* isolate = receiver->GetIsolate();
......@@ -16267,8 +16279,8 @@ int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) {
}
MaybeHandle<String> JSObject::ObjectProtoToString(Isolate* isolate,
Handle<Object> object) {
MaybeHandle<String> Object::ObjectProtoToString(Isolate* isolate,
Handle<Object> object) {
if (object->IsUndefined()) return isolate->factory()->undefined_to_string();
if (object->IsNull()) return isolate->factory()->null_to_string();
......@@ -16288,9 +16300,8 @@ MaybeHandle<String> JSObject::ObjectProtoToString(Isolate* isolate,
}
if (tag.is_null()) {
// TODO(adamk): class_name() is expensive, replace with instance type
// checks where possible.
tag = handle(receiver->class_name(), isolate);
ASSIGN_RETURN_ON_EXCEPTION(isolate, tag,
JSReceiver::BuiltinStringTag(receiver), String);
}
IncrementalStringBuilder builder(isolate);
......
// Copyright 2012 the V8 project authors. All rights reserved.
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -1359,6 +1359,10 @@ class Object {
inline void VerifyApiCallResultType();
// ES6 19.1.3.6 Object.prototype.toString
MUST_USE_RESULT static MaybeHandle<String> ObjectProtoToString(
Isolate* isolate, Handle<Object> object);
// Prints this object without details.
void ShortPrint(FILE* out = stdout);
......@@ -1887,6 +1891,10 @@ class JSReceiver: public HeapObject {
// Returns the class name ([[Class]] property in the specification).
String* class_name();
// Returns the builtin string tag used in Object.prototype.toString.
MUST_USE_RESULT static MaybeHandle<String> BuiltinStringTag(
Handle<JSReceiver> object);
// Returns the constructor name (the name (possibly, inferred name) of the
// function that was used to instantiate the object).
static Handle<String> GetConstructorName(Handle<JSReceiver> receiver);
......@@ -2472,10 +2480,6 @@ class JSObject: public JSReceiver {
static bool AllCanRead(LookupIterator* it);
static bool AllCanWrite(LookupIterator* it);
// ES6 19.1.3.6 Object.prototype.toString
MUST_USE_RESULT static MaybeHandle<String> ObjectProtoToString(
Isolate* isolate, Handle<Object> object);
private:
friend class JSReceiver;
friend class Object;
......
// Copyright 2014 the V8 project authors. All rights reserved.
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-tostring
// Flags: --harmony-tostring --harmony-proxies
var global = this;
......@@ -137,3 +137,25 @@ function testObjectToStringOwnNonStringValue() {
assertEquals("[object Object]", ({}).toString.call(obj));
}
testObjectToStringOwnNonStringValue();
// Proxies
function assertTag(tag, obj) {
assertEquals("[object " + tag + "]", Object.prototype.toString.call(obj));
}
assertTag("Object", new Proxy({}, {}));
assertTag("Array", new Proxy([], {}));
assertTag("Function", new Proxy(() => 42, {}));
assertTag("Foo", new Proxy(() => 42, {get() {return "Foo"}}));
assertTag("Function", new Proxy(() => 42, {get() {return 666}}));
revocable = Proxy.revocable([], {});
revocable.revoke();
assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);
handler = {};
revocable = Proxy.revocable([], handler);
handler.get = () => revocable.revoke();
assertThrows(() => Object.prototype.toString.call(revocable.proxy), TypeError);
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