function-return.js (2298B)
1 // |reftest| shell-option(--enable-shadow-realms) skip-if(!xulRuntime.shell) 2 3 // The output of Function.prototype.toString must match the |NativeFunction| production. 4 // https://tc39.es/ecma262/#sec-function.prototype.tostring 5 // 6 // NativeFunction : 7 // function NativeFunctionAccessor? PropertyName[~Yield, ~Await]? ( FormalParameters[~Yield, ~Await] ) { [ native code ] } 8 // 9 // NativeFunctionAccessor : 10 // get 11 // set 12 13 function assertMatchesNativeFunction(f) { 14 var source = f.toString(); 15 16 // Starts with "function". 17 assertEq(/^function\b/.test(source), true); 18 19 // Remove the optional |NativeFunctionAccessor| part. 20 var nativeAccesorRe = /^(?<start>\s*function)(?<accessor>\s+[gs]et)(?<end>\s+[^(].*)$/; 21 var match = nativeAccesorRe.exec(source); 22 if (match) { 23 source = match.groups.start + match.groups.end; 24 } 25 26 // The body must include the string "[native code". 27 var closeCurly = source.lastIndexOf("}"); 28 var openCurly = source.lastIndexOf("{"); 29 assertEq(openCurly < closeCurly, true); 30 31 var body = source.slice(openCurly + 1, closeCurly); 32 assertEq(/^\s*\[native code\]\s*$/.test(body), true); 33 34 // Verify |PropertyName| and |FormalParameters| are syntactically correct by parsing the source 35 // code. But we first need to replace the "[native code]" substring. 36 source = source.slice(0, openCurly) + "{}"; 37 38 // Also prepend "void" to parse the function source code as a FunctionExpression, because we 39 // don't necessarily have a name part. 40 source = "void " + source; 41 42 try { 43 Function(source); 44 } catch { 45 assertEq(true, false, `${source} doesn't match NativeFunction`); 46 } 47 } 48 49 let sr = new ShadowRealm(); 50 var f = sr.evaluate("function f() { }; f"); 51 52 assertMatchesNativeFunction(f); 53 54 f.name = "koala" 55 assertMatchesNativeFunction(f); 56 57 Object.defineProperty(f, "name", { writable: true, value: "koala" }); 58 assertMatchesNativeFunction(f); 59 60 f.name = "panda" 61 assertMatchesNativeFunction(f); 62 63 f.name = "has whitespace, therefore shouldn't match the PropertyName production"; 64 assertMatchesNativeFunction(f); 65 66 f.name = 123; 67 assertMatchesNativeFunction(f); 68 69 Object.defineProperty(f, "name", { get() { throw new Error("unexpected side-effect"); } }); 70 assertMatchesNativeFunction(f); 71 72 if (typeof reportCompare === 'function') 73 reportCompare(true, true);