New NativeFunction tests

This commit is contained in:
Gus Caplan 2020-07-25 19:26:36 -05:00 committed by Rick Waldron
parent ede5b2400f
commit 156186aee2
4 changed files with 102 additions and 515 deletions

View File

@ -7,13 +7,16 @@ info: |
the NativeFunction grammar production without requiring a correct tokeniser.
NativeFunction :
function _IdentifierName_ opt ( _FormalParameters_ ) { [ native code ] }
function _NativeFunctionAccessor_ opt _IdentifierName_ opt ( _FormalParameters_ ) { [ native code ] }
NativeFunctionAccessor :
get
set
defines:
- NATIVE_FUNCTION_RE
- assertToStringOrNativeFunction
- assertNativeFunction
---*/
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]*\}/;
const NATIVE_FUNCTION_RE = /\bfunction\b((get|set)\b)?[\s\S]*\([\s\S]*\)[\s\S]*\{[\s\S]*\[[\s\S]*\bnative\b[\s\S]+\bcode\b[\s\S]*\][\s\S]*\}/;
const assertToStringOrNativeFunction = function(fn, expected) {
const actual = "" + fn;

View File

@ -1,459 +0,0 @@
// 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
defines: [WellKnownIntrinsicObjects]
---*/
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

@ -6,43 +6,114 @@ 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.
If func is 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 ] }
function NativeFunctionAccessor_opt IdentifierName_opt ( FormalParameters ) { [ native code ] }
NativeFunctionAccessor :
get
set
includes: [nativeFunctionMatcher.js, wellKnownIntrinsicObjects.js]
features: [arrow-function]
includes: [nativeFunctionMatcher.js, fnGlobalObject.js]
features: [arrow-function, Reflect]
---*/
var visited = [];
var verified = [];
const visited = [];
function visit(ns, path) {
if (visited.includes(ns)) {
return;
}
visited.push(ns);
function visit(object) {
if (visited.includes(object)) {
if (typeof ns === 'function') {
assertNativeFunction(ns, path);
}
if (typeof ns !== 'function' && (typeof ns !== 'object' || ns === null)) {
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 */
const descriptors = Object.getOwnPropertyDescriptors(ns);
Reflect.ownKeys(descriptors)
.forEach((name) => {
const desc = descriptors[name];
const p = typeof name === 'symbol'
? `${path}[Symbol(${name.description})]`
: `${path}.${name}`;
if ('value' in desc) {
visit(desc.value, p);
} else {
visit(desc.get, p);
visit(desc.set, p);
}
}
}
});
}
visit(WellKnownIntrinsicObjects.map(wkio => wkio.reference));
assert.notSameValue(verified.length, 0);
[
// Function Properties of the Global Object
'eval',
'isFinite',
'isNaN',
'parseFloat',
'parseInt',
'decodeURI',
'decodeURIComponent',
'encodeURI',
'encodeURIComponent',
// Constructor Properties of the Global Object
'AggregateError',
'Array',
'ArrayBuffer',
'Boolean',
'BigInt',
'BigInt64Array',
'BigUint64Array',
'DataView',
'Date',
'Error',
'EvalError',
'FinalizationRegistry',
'Float32Array',
'Float64Array',
'Function',
'Int8Array',
'Int16Array',
'Int32Array',
'Map',
'Number',
'Object',
'Promise',
'Proxy',
'RangeError',
'ReferenceError',
'RegExp',
'Set',
'SharedArrayBuffer',
'String',
'Symbol',
'SyntaxError',
'TypeError',
'Uint8Array',
'Uint8ClampedArray',
'Uint16Array',
'Uint32Array',
'URIError',
'WeakMap',
'WeakRef',
'WeakSet',
// Other Properties of the Global Object
'Atomics',
'JSON',
'Math',
'Reflect',
].forEach((n) => {
const ref = fnGlobalObject()[n];
if (ref === undefined) {
return;
}
visit(ref, `globalThis.${n}`);
});
assert.notSameValue(visited.length, 0);

View File

@ -1,28 +0,0 @@
// 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);
}
});