summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/ShadowRealms/function-return.js
blob: d0853bcbb3b185e3e084cdb30f138c3e2d505135 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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);