Commit f7d7b5c6 authored by Adam Klein's avatar Adam Klein Committed by Commit Bot

ToString of a Proxied function should not throw

Without --harmony-function-tostring, anything other than a JSFunction
or JSBoundFunction throw when Function.prototype.toString is called on
them. But with the toString revision, anything callable allows toString
(and for non-Functions returns the good old "function () { [native code] }"
string).

Bug: v8:7484
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I3540e213a40992151761b59666fe36e0510da908
Reviewed-on: https://chromium-review.googlesource.com/932825
Commit-Queue: Adam Klein <adamk@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51489}
parent 8a78db6d
......@@ -305,9 +305,16 @@ BUILTIN(FunctionPrototypeToString) {
Handle<Object> receiver = args.receiver();
if (receiver->IsJSBoundFunction()) {
return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver));
} else if (receiver->IsJSFunction()) {
}
if (receiver->IsJSFunction()) {
return *JSFunction::ToString(Handle<JSFunction>::cast(receiver));
}
// With the revised toString behavior, all callable objects are valid
// receivers for this method.
if (FLAG_harmony_function_tostring && receiver->IsJSReceiver() &&
JSReceiver::cast(*receiver)->map()->is_callable()) {
return isolate->heap()->function_native_code_string();
}
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kNotGeneric,
isolate->factory()->NewStringFromAsciiChecked(
......
......@@ -79,6 +79,7 @@
V(Float64Array_string, "Float64Array") \
V(fraction_string, "fraction") \
V(Function_string, "Function") \
V(function_native_code_string, "function () { [native code] }") \
V(function_string, "function") \
V(function_to_string, "[object Function]") \
V(Generator_string, "Generator") \
......
......@@ -13212,9 +13212,6 @@ bool JSFunction::SetName(Handle<JSFunction> function, Handle<Name> name,
namespace {
char const kNativeCodeSource[] = "function () { [native code] }";
Handle<String> NativeCodeFunctionSourceString(
Handle<SharedFunctionInfo> shared_info) {
Isolate* const isolate = shared_info->GetIsolate();
......@@ -13231,7 +13228,7 @@ Handle<String> NativeCodeFunctionSourceString(
// static
Handle<String> JSBoundFunction::ToString(Handle<JSBoundFunction> function) {
Isolate* const isolate = function->GetIsolate();
return isolate->factory()->NewStringFromAsciiChecked(kNativeCodeSource);
return isolate->factory()->function_native_code_string();
}
......
......@@ -1287,8 +1287,7 @@ TestKeysThrow({
// ---------------------------------------------------------------------------
// String conversion (Object.prototype.toString,
// Object.prototype.toLocaleString,
// Function.prototype.toString)
// Object.prototype.toLocaleString)
var key
......@@ -1306,7 +1305,6 @@ function TestToString(handler) {
assertEquals(Symbol.toStringTag, key)
assertEquals("my_proxy", Object.prototype.toLocaleString.call(f))
assertEquals("toString", key)
assertThrows(function(){ Function.prototype.toString.call(f) })
var o = Object.create(p)
key = ""
......
// Copyright 2018 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: --noharmony-function-tostring
assertThrows(() => new Proxy(function() {}, {}).toString(), TypeError);
......@@ -122,3 +122,25 @@ testDynamicFunction("a, b", "return a");
testDynamicFunction("a,/*A*/b", "return a");
testDynamicFunction("/*A*/a,b", "return a");
testDynamicFunction("a,b", "return a/*A*/");
// Proxies of functions should not throw, but return a NativeFunction.
assertEquals("function () { [native code] }",
new Proxy(function () { hidden }, {}).toString());
assertEquals("function () { [native code] }",
new Proxy(() => { hidden }, {}).toString());
assertEquals("function () { [native code] }",
new Proxy(class {}, {}).toString());
assertEquals("function () { [native code] }",
new Proxy(function() { hidden }.bind({}), {}).toString());
assertEquals("function () { [native code] }",
new Proxy(function*() { hidden }, {}).toString());
assertEquals("function () { [native code] }",
new Proxy(async function() { hidden }, {}).toString());
assertEquals("function () { [native code] }",
new Proxy(async function*() { hidden }, {}).toString());
assertEquals("function () { [native code] }",
new Proxy({ method() { hidden } }.method, {}).toString());
// Non-callable proxies still throw.
assertThrows(() => Function.prototype.toString.call(new 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