Extensive Function toString updates for "Function.prototype.toString revision" proposal. (#1510)

Fixes gh-1453
This commit is contained in:
Rick Waldron 2018-04-19 16:44:52 -04:00 committed by Leo Balter
parent 6c6f02a693
commit c55d2ab7c3
19 changed files with 792 additions and 62 deletions

View File

@ -1,9 +1,14 @@
// Copyright (C) 2017 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: |
description: Assert _NativeFunction_ Syntax
info: |
This regex makes a best-effort determination that the tested string matches
the NativeFunction grammar production without requiring a correct tokeniser.
NativeFunction :
function _IdentifierName_ opt ( _FormalParameters_ ) { [ native code ] }
---*/
const NATIVE_FUNCTION_RE = /\bfunction\b[\s\S]*\([\s\S]*\)[\s\S]*\{[\s\S]*\[[\s\S]*\bnative\b[\s\S]+\bcode\b[\s\S]*\][\s\S]*\}/;
@ -12,11 +17,14 @@ const assertToStringOrNativeFunction = function(fn, expected) {
try {
assert.sameValue(actual, expected);
} catch (unused) {
assertNativeFunction(fn);
assertNativeFunction(fn, expected);
}
};
const assertNativeFunction = function(fn) {
const assertNativeFunction = function(fn, special) {
const actual = "" + fn;
assert(NATIVE_FUNCTION_RE.test(actual), "looks pretty much like a NativeFunction");
assert(
NATIVE_FUNCTION_RE.test(actual),
"Conforms to NativeFunction Syntax: '" + actual + "'." + (special ? "(" + special + ")" : "")
);
};

View File

@ -0,0 +1,458 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: |
An Array of all representable Well-Known Intrinsic Objects
---*/
const WellKnownIntrinsicObjects = [
{
intrinsicName: "%Array%",
globalNameOrSource: "Array"
},
{
intrinsicName: "%ArrayBuffer%",
globalNameOrSource: "ArrayBuffer"
},
{
intrinsicName: "%ArrayBufferPrototype%",
globalNameOrSource: "ArrayBuffer.prototype"
},
{
intrinsicName: "%ArrayIteratorPrototype%",
globalNameOrSource: "Object.getPrototypeOf([][Symbol.iterator]())"
},
{
intrinsicName: "%ArrayPrototype%",
globalNameOrSource: "Array.prototype"
},
{
intrinsicName: "%ArrayProto_entries%",
globalNameOrSource: "Array.prototype.entries"
},
{
intrinsicName: "%ArrayProto_forEach%",
globalNameOrSource: "Array.prototype.forEach"
},
{
intrinsicName: "%ArrayProto_keys%",
globalNameOrSource: "Array.prototype.keys"
},
{
intrinsicName: "%ArrayProto_values%",
globalNameOrSource: "Array.prototype.values"
},
{
intrinsicName: "%AsyncFromSyncIteratorPrototype%",
globalNameOrSource: "undefined"
},
{
intrinsicName: "%AsyncFunction%",
globalNameOrSource: "(async function() {}).constructor"
},
{
intrinsicName: "%AsyncFunctionPrototype%",
globalNameOrSource: "(async function() {}).constructor.prototype"
},
{
intrinsicName: "%AsyncGenerator%",
globalNameOrSource: "Object.getPrototypeOf((async function * () {})())"
},
{
intrinsicName: "%AsyncGeneratorFunction%",
globalNameOrSource: "Object.getPrototypeOf(async function * () {})"
},
{
intrinsicName: "%AsyncGeneratorPrototype%",
globalNameOrSource: "Object.getPrototypeOf(async function * () {}).prototype"
},
{
intrinsicName: "%AsyncIteratorPrototype%",
globalNameOrSource: "((async function * () {})())[Symbol.asyncIterator]()"
},
{
intrinsicName: "%Atomics%",
globalNameOrSource: "Atomics"
},
{
intrinsicName: "%Boolean%",
globalNameOrSource: "Boolean"
},
{
intrinsicName: "%BooleanPrototype%",
globalNameOrSource: "Boolean.prototype"
},
{
intrinsicName: "%DataView%",
globalNameOrSource: "DataView"
},
{
intrinsicName: "%DataViewPrototype%",
globalNameOrSource: "DataView.prototype"
},
{
intrinsicName: "%Date%",
globalNameOrSource: "Date"
},
{
intrinsicName: "%DatePrototype%",
globalNameOrSource: "Date.prototype"
},
{
intrinsicName: "%decodeURI%",
globalNameOrSource: "decodeURI"
},
{
intrinsicName: "%decodeURIComponent%",
globalNameOrSource: "decodeURIComponent"
},
{
intrinsicName: "%encodeURI%",
globalNameOrSource: "encodeURI"
},
{
intrinsicName: "%encodeURIComponent%",
globalNameOrSource: "encodeURIComponent"
},
{
intrinsicName: "%Error%",
globalNameOrSource: "Error"
},
{
intrinsicName: "%ErrorPrototype%",
globalNameOrSource: "Error.prototype"
},
{
intrinsicName: "%eval%",
globalNameOrSource: "eval"
},
{
intrinsicName: "%EvalError%",
globalNameOrSource: "EvalError"
},
{
intrinsicName: "%EvalErrorPrototype%",
globalNameOrSource: "EvalError.prototype"
},
{
intrinsicName: "%Float32Array%",
globalNameOrSource: "Float32Array"
},
{
intrinsicName: "%Float32ArrayPrototype%",
globalNameOrSource: "Float32Array.prototype"
},
{
intrinsicName: "%Float64Array%",
globalNameOrSource: "Float64Array"
},
{
intrinsicName: "%Float64ArrayPrototype%",
globalNameOrSource: "Float64Array.prototype"
},
{
intrinsicName: "%Function%",
globalNameOrSource: "Function"
},
{
intrinsicName: "%FunctionPrototype%",
globalNameOrSource: "Function.prototype"
},
{
intrinsicName: "%Generator%",
globalNameOrSource: "Object.getPrototypeOf((function * () {})())"
},
{
intrinsicName: "%GeneratorFunction%",
globalNameOrSource: "Object.getPrototypeOf(function * () {})"
},
{
intrinsicName: "%GeneratorPrototype%",
globalNameOrSource: "Object.getPrototypeOf(function * () {}).prototype"
},
{
intrinsicName: "%Int8Array%",
globalNameOrSource: "Int8Array"
},
{
intrinsicName: "%Int8ArrayPrototype%",
globalNameOrSource: "Int8Array.prototype"
},
{
intrinsicName: "%Int16Array%",
globalNameOrSource: "Int16Array"
},
{
intrinsicName: "%Int16ArrayPrototype%",
globalNameOrSource: "Int16Array.prototype"
},
{
intrinsicName: "%Int32Array%",
globalNameOrSource: "Int32Array"
},
{
intrinsicName: "%Int32ArrayPrototype%",
globalNameOrSource: "Int32Array.prototype"
},
{
intrinsicName: "%isFinite%",
globalNameOrSource: "isFinite"
},
{
intrinsicName: "%isNaN%",
globalNameOrSource: "isNaN"
},
{
intrinsicName: "%IteratorPrototype%",
globalNameOrSource: "Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))"
},
{
intrinsicName: "%JSON%",
globalNameOrSource: "JSON"
},
{
intrinsicName: "%JSONParse%",
globalNameOrSource: "JSON.parse"
},
{
intrinsicName: "%Map%",
globalNameOrSource: "Map"
},
{
intrinsicName: "%MapIteratorPrototype%",
globalNameOrSource: "Object.getPrototypeOf(new Map()[Symbol.iterator]())"
},
{
intrinsicName: "%MapPrototype%",
globalNameOrSource: "Map.prototype"
},
{
intrinsicName: "%Math%",
globalNameOrSource: "Math"
},
{
intrinsicName: "%Number%",
globalNameOrSource: "Number"
},
{
intrinsicName: "%NumberPrototype%",
globalNameOrSource: "Number.prototype"
},
{
intrinsicName: "%Object%",
globalNameOrSource: "Object"
},
{
intrinsicName: "%ObjectPrototype%",
globalNameOrSource: "Object.prototype"
},
{
intrinsicName: "%ObjProto_toString%",
globalNameOrSource: "Object.prototype.toString"
},
{
intrinsicName: "%ObjProto_valueOf%",
globalNameOrSource: "Object.prototype.valueOf"
},
{
intrinsicName: "%parseFloat%",
globalNameOrSource: "parseFloat"
},
{
intrinsicName: "%parseInt%",
globalNameOrSource: "parseInt"
},
{
intrinsicName: "%Promise%",
globalNameOrSource: "Promise"
},
{
intrinsicName: "%PromisePrototype%",
globalNameOrSource: "Promise.prototype"
},
{
intrinsicName: "%PromiseProto_then%",
globalNameOrSource: "Promise.prototype.then"
},
{
intrinsicName: "%Promise_all%",
globalNameOrSource: "Promise.all"
},
{
intrinsicName: "%Promise_reject%",
globalNameOrSource: "Promise.reject"
},
{
intrinsicName: "%Promise_resolve%",
globalNameOrSource: "Promise.resolve"
},
{
intrinsicName: "%Proxy%",
globalNameOrSource: "Proxy"
},
{
intrinsicName: "%RangeError%",
globalNameOrSource: "RangeError"
},
{
intrinsicName: "%RangeErrorPrototype%",
globalNameOrSource: "RangeError.prototype"
},
{
intrinsicName: "%ReferenceError%",
globalNameOrSource: "ReferenceError"
},
{
intrinsicName: "%ReferenceErrorPrototype%",
globalNameOrSource: "ReferenceError.prototype"
},
{
intrinsicName: "%Reflect%",
globalNameOrSource: "Reflect"
},
{
intrinsicName: "%RegExp%",
globalNameOrSource: "RegExp"
},
{
intrinsicName: "%RegExpPrototype%",
globalNameOrSource: "RegExp.prototype"
},
{
intrinsicName: "%Set%",
globalNameOrSource: "Set"
},
{
intrinsicName: "%SetIteratorPrototype%",
globalNameOrSource: "Object.getPrototypeOf(new Set()[Symbol.iterator]())"
},
{
intrinsicName: "%SetPrototype%",
globalNameOrSource: "Set.prototype"
},
{
intrinsicName: "%SharedArrayBuffer%",
globalNameOrSource: "SharedArrayBuffer"
},
{
intrinsicName: "%SharedArrayBufferPrototype%",
globalNameOrSource: "SharedArrayBuffer.prototype"
},
{
intrinsicName: "%String%",
globalNameOrSource: "String"
},
{
intrinsicName: "%StringIteratorPrototype%",
globalNameOrSource: "Object.getPrototypeOf(new String()[Symbol.iterator]())"
},
{
intrinsicName: "%StringPrototype%",
globalNameOrSource: "String.prototype"
},
{
intrinsicName: "%Symbol%",
globalNameOrSource: "Symbol"
},
{
intrinsicName: "%SymbolPrototype%",
globalNameOrSource: "Symbol.prototype"
},
{
intrinsicName: "%SyntaxError%",
globalNameOrSource: "SyntaxError"
},
{
intrinsicName: "%SyntaxErrorPrototype%",
globalNameOrSource: "SyntaxError.prototype"
},
{
intrinsicName: "%ThrowTypeError%",
globalNameOrSource: "(function() { 'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'callee').get })()"
},
{
intrinsicName: "%TypedArray%",
globalNameOrSource: "Object.getPrototypeOf(Uint8Array)"
},
{
intrinsicName: "%TypedArrayPrototype%",
globalNameOrSource: "Object.getPrototypeOf(Uint8Array).prototype"
},
{
intrinsicName: "%TypeError%",
globalNameOrSource: "TypeError"
},
{
intrinsicName: "%TypeErrorPrototype%",
globalNameOrSource: "TypeError.prototype"
},
{
intrinsicName: "%Uint8Array%",
globalNameOrSource: "Uint8Array"
},
{
intrinsicName: "%Uint8ArrayPrototype%",
globalNameOrSource: "Uint8Array.prototype"
},
{
intrinsicName: "%Uint8ClampedArray%",
globalNameOrSource: "Uint8ClampedArray"
},
{
intrinsicName: "%Uint8ClampedArrayPrototype%",
globalNameOrSource: "Uint8ClampedArray.prototype"
},
{
intrinsicName: "%Uint16Array%",
globalNameOrSource: "Uint16Array"
},
{
intrinsicName: "%Uint16ArrayPrototype%",
globalNameOrSource: "Uint16Array.prototype"
},
{
intrinsicName: "%Uint32Array%",
globalNameOrSource: "Uint32Array"
},
{
intrinsicName: "%Uint32ArrayPrototype%",
globalNameOrSource: "Uint32Array.prototype"
},
{
intrinsicName: "%URIError%",
globalNameOrSource: "URIError"
},
{
intrinsicName: "%URIErrorPrototype%",
globalNameOrSource: "URIError.prototype"
},
{
intrinsicName: "%WeakMap%",
globalNameOrSource: "WeakMap"
},
{
intrinsicName: "%WeakMapPrototype%",
globalNameOrSource: "WeakMap.prototype"
},
{
intrinsicName: "%WeakSet%",
globalNameOrSource: "WeakSet"
},
{
intrinsicName: "%WeakSetPrototype%",
globalNameOrSource: "WeakSet.prototype"
}
];
WellKnownIntrinsicObjects.forEach(wkio => {
var actual;
try {
actual = new Function("return " + wkio.globalNameOrSource)();
} catch (exception) {
// Nothing to do here.
}
wkio.reference = actual;
});

View File

@ -1,12 +0,0 @@
// Copyright (C) 2018 Michael Ficarra. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: Function.prototype.toString on anonymous well-known intrinsic function objects
includes: [nativeFunctionMatcher.js]
---*/
var ThrowTypeError = (function() { "use strict"; return Object.getOwnPropertyDescriptor(arguments, "callee").get })()
assert.sameValue(ThrowTypeError.name, "");
assertNativeFunction(ThrowTypeError);

View File

@ -1,12 +1,17 @@
// Copyright (C) 2016 Michael Ficarra. All rights reserved.
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: Function.prototype.toString on bound function exotic objects
description: >
toString bound function does not throw (bound Function Expression)
info: |
...
If func is a Bound Function exotic object or a built-in Function object,
then return an implementation-dependent String source code representation
of func. The representation must have the syntax of a NativeFunction
...
includes: [nativeFunctionMatcher.js]
---*/
let f = function(){}.bind(null);
assertNativeFunction(f);
assertNativeFunction(function() {}.bind({}));

View File

@ -0,0 +1,48 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of built-in Function object
info: |
...
If func is a Bound Function exotic object or a built-in Function object, then return an implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
includes: [fnGlobalObject.js, nativeFunctionMatcher.js, wellKnownIntrinsicObjects.js]
features: [arrow-function]
---*/
var visited = [];
var verified = [];
function visit(object) {
if (visited.includes(object)) {
return;
}
visited.push(object);
if (typeof object === "function") {
assertNativeFunction(object);
verified.push(object.name);
}
for (var property of Object.getOwnPropertyNames(object)) {
if (typeof object[property] === "function" ||
typeof object[property] === "object") {
try {
visit(object[property], assertNativeFunction);
} catch(error) {
/* we don't actually want to do anything about failures here */
}
}
}
}
visit(WellKnownIntrinsicObjects.map(wkio => wkio.reference));
assert.notSameValue(verified.length, 0);

View File

@ -1,24 +0,0 @@
// Copyright (C) 2016 Michael Ficarra. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: Function.prototype.toString on well-known intrinsic function objects
includes: [nativeFunctionMatcher.js]
---*/
let intrinsics = {
Array, ArrayBuffer, Boolean, DataView, Date, decodeURI, decodeURIComponent, encodeURI,
encodeURIComponent, Error, eval, EvalError, Float32Array, Float64Array, Function, Int8Array,
Int16Array, Int32Array, isFinite, isNaN, Map, Number, Object, parseFloat, parseInt, Promise,
Proxy, RangeError, ReferenceError, RegExp, Set, String, Symbol, SyntaxError, TypeError,
Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array, URIError, WeakMap, WeakSet,
};
for (let intrinsicName in intrinsics) {
let intrinsic = intrinsics[intrinsicName];
let str = Function.prototype.toString.call(intrinsic);
assert.sameValue(typeof str, "string");
assert(RegExp('\\b' + intrinsicName + '\\b').test(str), "contains its name");
assertNativeFunction(intrinsic);
}

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (Arrow Function)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [arrow-function, Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy(() => {}, {}));
assertNativeFunction(new Proxy(() => {}, { apply() {} }).apply);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (Async Function Expression)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [async-functions, Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy(async function() {}, {}));
assertNativeFunction(new Proxy(async function() {}, { apply() {} }).apply);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (Async Generator Function Expression)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [async-functions, generators, Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy(async function * () {}, {}));
assertNativeFunction(new Proxy(async function * () {}, { apply() {} }).apply);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (Async Generator Method Definition)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [async-functions, generators, Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy({ async * method() {} }.method, {}));
assertNativeFunction(new Proxy({ async * method() {} }.method, { apply() {} }).apply);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (Async Method Definition)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [async-functions, generators, Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy({ async method() {} }.method, {}));
assertNativeFunction(new Proxy({ async method() {} }.method, { apply() {} }).apply);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (bound Function Expression)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy(function() {}.bind({}), {}));
assertNativeFunction(new Proxy(function() {}.bind({}), { apply() {} }).apply);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (Class Expression)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [class, Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy(class {}, {}));
assertNativeFunction(new Proxy(class {}, { apply() {} }).apply);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (Function Expression)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy(function() {}, {}));
assertNativeFunction(new Proxy(function() {}, { apply() {} }).apply);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (Generator Function Expression)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [generators, Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy(function * () {}, {}));
assertNativeFunction(new Proxy(function * () {}, { apply() {} }).apply);

View File

@ -0,0 +1,22 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for function target does not throw (Method Definition)
info: |
...
If Type(func) is Object and IsCallable(func) is true, then return an
implementation-dependent String source code representation of func.
The representation must have the syntax of a NativeFunction.
...
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
features: [Proxy]
includes: [nativeFunctionMatcher.js]
---*/
assertNativeFunction(new Proxy({ method() {} }.method, {}));
assertNativeFunction(new Proxy({ method() {} }.method, { apply() {} }).apply);

View File

@ -0,0 +1,16 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Proxy for non-callable target throws
info: |
...
Throw a TypeError exception.
features: [Proxy]
---*/
assert.throws(TypeError, function() {
Function.prototype.toString.call(new Proxy({}, {}));
});

View File

@ -1,17 +0,0 @@
// Copyright (C) 2018 Michael Ficarra. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: Function.prototype.toString on a proxied function
info: |
Function.prototype.toString accepts any callable, including proxied
functions, and produces a NativeFunction
includes: [nativeFunctionMatcher.js]
---*/
const f = new Proxy(function(){}, {});
assertNativeFunction(f);
const g = new Proxy(f, { apply() {} });
assertNativeFunction(g);

View File

@ -0,0 +1,28 @@
// Copyright (C) 2016 Michael Ficarra. All rights reserved.
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-function.prototype.tostring
description: >
toString of Well-Known Intrinsic Object
info: |
...
If func is a Bound Function exotic object or a built-in Function object, then return an implementation-dependent String source code representation of func. The representation must have the syntax of a NativeFunction. Additionally, if func is a Well-known Intrinsic Object and is not identified as an anonymous function, the portion of the returned String that would be matched by IdentifierName must be the initial value of the name property of func.
NativeFunction:
function IdentifierName_opt ( FormalParameters ) { [ native code ] }
includes: [nativeFunctionMatcher.js, wellKnownIntrinsicObjects.js]
features: [destructuring-binding, template]
---*/
WellKnownIntrinsicObjects.forEach(({intrinsicName, reference}) => {
if (typeof reference === "function") {
assert.sameValue(
("" + reference).includes(reference.name), true,
`toString of Well-Known Intrinsic Object function should produce a string that matches NativeFunction syntax:\n${reference}\nis missing "${reference.name}"\n\n`
);
assertNativeFunction(reference, intrinsicName);
}
});