summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/function
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/function')
-rw-r--r--js/src/jit-test/tests/function/bug-1751660.js26
-rw-r--r--js/src/jit-test/tests/function/function-displayName-computed.js74
-rw-r--r--js/src/jit-test/tests/function/function-toString-discard-source-name.js222
-rw-r--r--js/src/jit-test/tests/function/function-toString-discard-source.js213
-rw-r--r--js/src/jit-test/tests/function/function-toString-lazy-name.js7
5 files changed, 542 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/function/bug-1751660.js b/js/src/jit-test/tests/function/bug-1751660.js
new file mode 100644
index 0000000000..98317e7878
--- /dev/null
+++ b/js/src/jit-test/tests/function/bug-1751660.js
@@ -0,0 +1,26 @@
+function foo() {}
+
+function bar(o) {
+ function nested() {
+ with (o) {
+ return Object(...arguments);
+ }
+ }
+
+ // We need an arbitrary IC before the OSR loop.
+ foo();
+
+ // Trigger on-stack-replacement.
+ for(let i = 0; i < 100; i++) {}
+
+ // Make the call.
+ return nested();
+}
+
+// Trigger OSR compilation.
+for (var i = 0; i < 5; i++) {
+ bar({});
+}
+
+// Call passing in the function itself.
+print(bar(bar));
diff --git a/js/src/jit-test/tests/function/function-displayName-computed.js b/js/src/jit-test/tests/function/function-displayName-computed.js
new file mode 100644
index 0000000000..d2f1a77eb8
--- /dev/null
+++ b/js/src/jit-test/tests/function/function-displayName-computed.js
@@ -0,0 +1,74 @@
+// |jit-test| skip-if: isLcovEnabled()
+// Guessed Atoms tests.
+// Test String literals
+var obj = {
+ ["func"]: function() {return function() {} },
+ ["arrowFunc"]: ()=>{return function() {} },
+ ["method"]() {return function() {} },
+ ["nonAnonymousFunc"]: function F() {return function() {} },
+ get ["getter"]() {return function() {} },
+};
+
+
+assertEq(displayName(obj.func()), "func/<");
+assertEq(displayName(obj.arrowFunc()), "arrowFunc/<");
+assertEq(displayName(obj.method()), "method/<");
+assertEq(displayName(obj.nonAnonymousFunc()), "F/<");
+
+// We don't support guessed name for accessor
+assertEq(displayName(obj.getter), "");
+
+let dummy = class {
+ ["func"]() {return function() {} }
+ ["arrowFunc"] = ()=>{return function() {} };
+ ["method"]() {return function() {} }
+ get ["getter"]() {return function() {} }
+};
+
+dum = new dummy();
+assertEq(displayName(dum.func()), "func/<");
+// We don't support guessed name for class field with computed name
+assertEq(displayName(dum.arrowFunc()), "dummy</</<");
+assertEq(displayName(dum.method()), "method/<");
+// We don't support guessed name for accessor
+assertEq(displayName(dummy.prototype.getter), "dummy</<");
+
+
+// Test numeric literals
+var objN = {
+ [1]: function() {return function() {}},
+ [5]: ()=>{return function() {}},
+ [7] () {return function() {}},
+ [8]: class {},
+ [9]: function F() {return function() {}},
+ [10]: class C{},
+ get [11]() {return function() {}},
+};
+assertEq(displayName(objN[1]()), "1/<");
+assertEq(displayName(objN[5]()), "5/<");
+assertEq(displayName(objN[7]()), "7/<");
+assertEq(displayName(objN[8]), "8");
+assertEq(displayName(objN[9]()), "F/<");
+assertEq(displayName(objN[10]), "C");
+// We don't support guessed name for accessor
+assertEq(displayName(objN[11]), "objN/<");
+
+let foo = class {
+ [1] () {return function() {} }
+ [5] = ()=>{return function() {} };
+ [7] () {return function() {} }
+ get [11]() {return function() {} }
+};
+
+f = new foo();
+
+assertEq(displayName(f[1]()), "1/<");
+// We don't support guessed name for class field with computed name
+assertEq(displayName(f[5]()), "foo</</<");
+assertEq(displayName(f[7]()), "7/<");
+assertEq(displayName(f[11]), "foo</<");
+
+// Native built-in accessor name, which is lazily created.
+
+assertEq(displayName(Object.getOwnPropertyDescriptor(Map.prototype, "size").get), "get size");
+assertEq(displayName(Object.getOwnPropertyDescriptor(RegExp.prototype, "flags").get), "get flags");
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..be5622e6ee
--- /dev/null
+++ b/js/src/jit-test/tests/function/function-toString-discard-source-name.js
@@ -0,0 +1,222 @@
+// 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 {};
+var classExprAnonField = class {x = 1};
+
+this.classDecl = classDecl;
+`);
+
+assertFunctionName(classDecl, "classDecl");
+assertFunctionName(classExpr, "C");
+assertFunctionName(classExprAnon, undefined);
+assertFunctionName(classExprAnonField, undefined);
+
+
+// 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()");
diff --git a/js/src/jit-test/tests/function/function-toString-discard-source.js b/js/src/jit-test/tests/function/function-toString-discard-source.js
new file mode 100644
index 0000000000..3bd183c538
--- /dev/null
+++ b/js/src/jit-test/tests/function/function-toString-discard-source.js
@@ -0,0 +1,213 @@
+// 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 reportMatch(pattern, str) {
+ assertEq(pattern.test(str), true);
+}
+
+// Function declarations.
+
+eval(`
+function funDecl() {}
+function* genDecl() {}
+async function asyncFunDecl() {}
+async function* asyncGenDecl() {}
+`);
+
+reportMatch(nativeCode, funDecl.toString());
+reportMatch(nativeCode, genDecl.toString());
+reportMatch(nativeCode, asyncFunDecl.toString());
+reportMatch(nativeCode, asyncGenDecl.toString());
+
+
+// Named function expressions.
+
+eval(`
+var funExpr = function fn() {};
+var genExpr = function* fn() {};
+var asyncFunExpr = async function fn() {};
+var asyncGenExpr = async function* fn() {};
+`);
+
+reportMatch(nativeCode, funExpr.toString());
+reportMatch(nativeCode, genExpr.toString());
+reportMatch(nativeCode, asyncFunExpr.toString());
+reportMatch(nativeCode, asyncGenExpr.toString());
+
+
+// Anonymous function expressions.
+
+eval(`
+var funExprAnon = function() {};
+var genExprAnon = function*() {};
+var asyncFunExprAnon = async function() {};
+var asyncGenExprAnon = async function*() {};
+`);
+
+reportMatch(nativeCode, funExprAnon.toString());
+reportMatch(nativeCode, genExprAnon.toString());
+reportMatch(nativeCode, asyncFunExprAnon.toString());
+reportMatch(nativeCode, asyncGenExprAnon.toString());
+
+
+// Class declarations and expressions (implicit constructor).
+eval(`
+class classDecl {}
+var classExpr = class C {};
+var classExprAnon = class {};
+
+this.classDecl = classDecl;
+`);
+
+reportMatch(nativeCode, classDecl.toString());
+reportMatch(nativeCode, classExpr.toString());
+reportMatch(nativeCode, classExprAnon.toString());
+
+
+// Class declarations and expressions (explicit constructor).
+eval(`
+class classDecl { constructor() {} }
+var classExpr = class C { constructor() {} };
+var classExprAnon = class { constructor() {} };
+
+this.classDecl = classDecl;
+`);
+
+reportMatch(nativeCode, classDecl.toString());
+reportMatch(nativeCode, classExpr.toString());
+reportMatch(nativeCode, classExprAnon.toString());
+
+
+// Method definitions (identifier names).
+eval(`
+var obj = {
+ m() {},
+ *gm() {},
+ async am() {},
+ async* agm() {},
+ get x() {},
+ set x(_) {},
+};
+`);
+
+reportMatch(nativeCode, obj.m.toString());
+reportMatch(nativeCode, obj.gm.toString());
+reportMatch(nativeCode, obj.am.toString());
+reportMatch(nativeCode, obj.agm.toString());
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(obj, "x").get.toString());
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(obj, "x").set.toString());
+
+
+// Method definitions (string names).
+eval(`
+var obj = {
+ "foo m"() {},
+ * "foo gm"() {},
+ async "foo am"() {},
+ async* "foo agm"() {},
+ get "foo x"() {},
+ set "foo x"(_) {},
+};
+`);
+
+reportMatch(nativeCode, obj["foo m"].toString());
+reportMatch(nativeCode, obj["foo gm"].toString());
+reportMatch(nativeCode, obj["foo am"].toString());
+reportMatch(nativeCode, obj["foo agm"].toString());
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(obj, "foo x").get.toString());
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(obj, "foo x").set.toString());
+
+
+// Method definitions (number names).
+eval(`
+var obj = {
+ 100() {},
+ *200() {},
+ async 300() {},
+ async* 400() {},
+ get 500() {},
+ set 500(_) {},
+};
+`);
+
+reportMatch(nativeCode, obj[100].toString());
+reportMatch(nativeCode, obj[200].toString());
+reportMatch(nativeCode, obj[300].toString());
+reportMatch(nativeCode, obj[400].toString());
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(obj, 500).get.toString());
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(obj, 500).set.toString());
+
+
+// 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](_) {},
+};
+`);
+
+reportMatch(nativeCode, obj[sym1].toString());
+reportMatch(nativeCode, obj[sym2].toString());
+reportMatch(nativeCode, obj[sym3].toString());
+reportMatch(nativeCode, obj[sym4].toString());
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(obj, sym5).get.toString());
+reportMatch(nativeCode, Object.getOwnPropertyDescriptor(obj, sym5).set.toString());
+
+
+// Arrow functions.
+eval(`
+var arrowFn = () => {};
+var asyncArrowFn = () => {};
+`);
+
+reportMatch(nativeCode, arrowFn.toString());
+reportMatch(nativeCode, asyncArrowFn.toString());
+
+
+// asm.js functions.
+eval(`
+function asm() {
+ "use asm";
+ function f(){ return 0|0; }
+ return {f: f};
+}
+`);
+
+reportMatch(nativeCode, asm.toString());
+reportMatch(nativeCode, asm().f.toString());
+}
+
+var g = newGlobal({ discardSource: true });
+g.evaluate(test.toString() + "test()");
diff --git a/js/src/jit-test/tests/function/function-toString-lazy-name.js b/js/src/jit-test/tests/function/function-toString-lazy-name.js
new file mode 100644
index 0000000000..088cd26e39
--- /dev/null
+++ b/js/src/jit-test/tests/function/function-toString-lazy-name.js
@@ -0,0 +1,7 @@
+assertEq(Map.prototype.set.toString().includes("function set()"), true);
+assertEq(Object.getOwnPropertyDescriptor(Map.prototype, 'size').get.toString().includes("function size()"), true);
+assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.toString().includes("function flags()"), true);
+
+assertEq(Map.prototype.set.toSource().includes("function set()"), true);
+assertEq(Object.getOwnPropertyDescriptor(Map.prototype, 'size').get.toSource().includes("function get size()"), true);
+assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.toSource().includes("function get flags()"), true);