summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/function/function-toString-discard-source-name.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/function/function-toString-discard-source-name.js')
-rw-r--r--js/src/jit-test/tests/function/function-toString-discard-source-name.js220
1 files changed, 220 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/function/function-toString-discard-source-name.js b/js/src/jit-test/tests/function/function-toString-discard-source-name.js
new file mode 100644
index 0000000000..b76aeb3206
--- /dev/null
+++ b/js/src/jit-test/tests/function/function-toString-discard-source-name.js
@@ -0,0 +1,220 @@
+// Repeats the test from 'function/function-toString-discard-source.js' and
+// additionally verifies the name matches the expected value.
+//
+// This behaviour is not required by the ECMAScript standard.
+
+// The Function.prototype.toString() representation of sourceless functions
+// must match the NativeFunction syntax.
+
+function test() {
+// Greatly (!) simplified patterns for the PropertyName production.
+var propertyName = [
+ // PropertyName :: LiteralPropertyName :: IdentifierName
+ "\\w+",
+
+ // PropertyName :: LiteralPropertyName :: StringLiteral
+ "(?:'[^']*')",
+ "(?:\"[^\"]*\")",
+
+ // PropertyName :: LiteralPropertyName :: NumericLiteral
+ "\\d+",
+
+ // PropertyName :: ComputedPropertyName
+ "(?:\\[[^\\]]+\\])",
+].join("|")
+
+var nativeCode = RegExp([
+ "^", "function", ("(" + propertyName + ")?"), "\\(", "\\)", "\\{", "\\[native code\\]", "\\}", "$"
+].join("\\s*"));
+
+function assertFunctionName(fun, expected) {
+ var match = nativeCode.exec(fun.toString());
+ assertEq(match[1], expected);
+}
+
+
+// Function declarations.
+
+eval(`
+function funDecl() {}
+function* genDecl() {}
+async function asyncFunDecl() {}
+async function* asyncGenDecl() {}
+`);
+
+assertFunctionName(funDecl, "funDecl");
+assertFunctionName(genDecl, "genDecl");
+assertFunctionName(asyncFunDecl, "asyncFunDecl");
+assertFunctionName(asyncGenDecl, "asyncGenDecl");
+
+
+// Named function expressions.
+
+eval(`
+var funExpr = function fn() {};
+var genExpr = function* fn() {};
+var asyncFunExpr = async function fn() {};
+var asyncGenExpr = async function* fn() {};
+`);
+
+assertFunctionName(funExpr, "fn");
+assertFunctionName(genExpr, "fn");
+assertFunctionName(asyncFunExpr, "fn");
+assertFunctionName(asyncGenExpr, "fn");
+
+
+// Anonymous function expressions.
+
+eval(`
+var funExprAnon = function() {};
+var genExprAnon = function*() {};
+var asyncFunExprAnon = async function() {};
+var asyncGenExprAnon = async function*() {};
+`);
+
+assertFunctionName(funExprAnon, undefined);
+assertFunctionName(genExprAnon, undefined);
+assertFunctionName(asyncFunExprAnon, undefined);
+assertFunctionName(asyncGenExprAnon, undefined);
+
+
+// Class declarations and expressions (implicit constructor).
+eval(`
+class classDecl {}
+var classExpr = class C {};
+var classExprAnon = class {};
+
+this.classDecl = classDecl;
+`);
+
+assertFunctionName(classDecl, "classDecl");
+assertFunctionName(classExpr, "C");
+assertFunctionName(classExprAnon, "classExprAnon");
+
+
+// Class declarations and expressions (explicit constructor).
+eval(`
+class classDecl { constructor() {} }
+var classExpr = class C { constructor() {} };
+var classExprAnon = class { constructor() {} };
+
+this.classDecl = classDecl;
+`);
+
+assertFunctionName(classDecl, "classDecl");
+assertFunctionName(classExpr, "C");
+assertFunctionName(classExprAnon, undefined);
+
+
+// Method definitions (identifier names).
+eval(`
+var obj = {
+ m() {},
+ *gm() {},
+ async am() {},
+ async* agm() {},
+ get x() {},
+ set x(_) {},
+};
+`);
+
+assertFunctionName(obj.m, undefined);
+assertFunctionName(obj.gm, undefined);
+assertFunctionName(obj.am, undefined);
+assertFunctionName(obj.agm, undefined);
+assertFunctionName(Object.getOwnPropertyDescriptor(obj, "x").get, undefined);
+assertFunctionName(Object.getOwnPropertyDescriptor(obj, "x").set, undefined);
+
+
+// Method definitions (string names).
+eval(`
+var obj = {
+ "foo m"() {},
+ * "foo gm"() {},
+ async "foo am"() {},
+ async* "foo agm"() {},
+ get "foo x"() {},
+ set "foo x"(_) {},
+};
+`);
+
+assertFunctionName(obj["foo m"], undefined);
+assertFunctionName(obj["foo gm"], undefined);
+assertFunctionName(obj["foo am"], undefined);
+assertFunctionName(obj["foo agm"], undefined);
+assertFunctionName(Object.getOwnPropertyDescriptor(obj, "foo x").get, undefined);
+assertFunctionName(Object.getOwnPropertyDescriptor(obj, "foo x").set, undefined);
+
+
+// Method definitions (number names).
+eval(`
+var obj = {
+ 100() {},
+ *200() {},
+ async 300() {},
+ async* 400() {},
+ get 500() {},
+ set 500(_) {},
+};
+`);
+
+assertFunctionName(obj[100], undefined);
+assertFunctionName(obj[200], undefined);
+assertFunctionName(obj[300], undefined);
+assertFunctionName(obj[400], undefined);
+assertFunctionName(Object.getOwnPropertyDescriptor(obj, 500).get, undefined);
+assertFunctionName(Object.getOwnPropertyDescriptor(obj, 500).set, undefined);
+
+
+// Method definitions (computed property names).
+
+var sym1 = Symbol();
+var sym2 = Symbol("desc");
+var sym3 = Symbol.for("reg-sym");
+var sym4 = Symbol.match;
+var sym5 = Symbol();
+
+eval(`
+var obj = {
+ [sym1]() {},
+ *[sym2]() {},
+ async [sym3]() {},
+ async* [sym4]() {},
+ get [sym5]() {},
+ set [sym5](_) {},
+};
+`);
+
+assertFunctionName(obj[sym1], undefined);
+assertFunctionName(obj[sym2], undefined);
+assertFunctionName(obj[sym3], undefined);
+assertFunctionName(obj[sym4], undefined);
+assertFunctionName(Object.getOwnPropertyDescriptor(obj, sym5).get, undefined);
+assertFunctionName(Object.getOwnPropertyDescriptor(obj, sym5).set, undefined);
+
+
+// Arrow functions.
+eval(`
+var arrowFn = () => {};
+var asyncArrowFn = () => {};
+`);
+
+assertFunctionName(arrowFn, undefined);
+assertFunctionName(asyncArrowFn, undefined);
+
+
+// asm.js functions.
+eval(`
+function asm() {
+ "use asm";
+ function f(){ return 0|0; }
+ return {f: f};
+}
+`);
+
+assertFunctionName(asm, "asm");
+assertFunctionName(asm().f, "f");
+}
+
+var g = newGlobal({ discardSource: true });
+g.evaluate(test.toString() + "test()");