diff options
Diffstat (limited to '')
-rw-r--r-- | js/src/tests/non262/ShadowRealms/function-return.js | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/js/src/tests/non262/ShadowRealms/function-return.js b/js/src/tests/non262/ShadowRealms/function-return.js new file mode 100644 index 0000000000..d0853bcbb3 --- /dev/null +++ b/js/src/tests/non262/ShadowRealms/function-return.js @@ -0,0 +1,73 @@ +// |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) + +// The output of Function.prototype.toString must match the |NativeFunction| production. +// https://tc39.es/ecma262/#sec-function.prototype.tostring +// +// NativeFunction : +// function NativeFunctionAccessor? PropertyName[~Yield, ~Await]? ( FormalParameters[~Yield, ~Await] ) { [ native code ] } +// +// NativeFunctionAccessor : +// get +// set + +function assertMatchesNativeFunction(f) { + var source = f.toString(); + + // Starts with "function". + assertEq(/^function\b/.test(source), true); + + // Remove the optional |NativeFunctionAccessor| part. + var nativeAccesorRe = /^(?<start>\s*function)(?<accessor>\s+[gs]et)(?<end>\s+[^(].*)$/; + var match = nativeAccesorRe.exec(source); + if (match) { + source = match.groups.start + match.groups.end; + } + + // The body must include the string "[native code". + var closeCurly = source.lastIndexOf("}"); + var openCurly = source.lastIndexOf("{"); + assertEq(openCurly < closeCurly, true); + + var body = source.slice(openCurly + 1, closeCurly); + assertEq(/^\s*\[native code\]\s*$/.test(body), true); + + // Verify |PropertyName| and |FormalParameters| are syntactically correct by parsing the source + // code. But we first need to replace the "[native code]" substring. + source = source.slice(0, openCurly) + "{}"; + + // Also prepend "void" to parse the function source code as a FunctionExpression, because we + // don't necessarily have a name part. + source = "void " + source; + + try { + Function(source); + } catch { + assertEq(true, false, `${source} doesn't match NativeFunction`); + } +} + +let sr = new ShadowRealm(); +var f = sr.evaluate("function f() { }; f"); + +assertMatchesNativeFunction(f); + +f.name = "koala" +assertMatchesNativeFunction(f); + +Object.defineProperty(f, "name", { writable: true, value: "koala" }); +assertMatchesNativeFunction(f); + +f.name = "panda" +assertMatchesNativeFunction(f); + +f.name = "has whitespace, therefore shouldn't match the PropertyName production"; +assertMatchesNativeFunction(f); + +f.name = 123; +assertMatchesNativeFunction(f); + +Object.defineProperty(f, "name", { get() { throw new Error("unexpected side-effect"); } }); +assertMatchesNativeFunction(f); + +if (typeof reportCompare === 'function') + reportCompare(true, true); |