diff options
Diffstat (limited to '')
4 files changed, 530 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..9a19fe1a4f --- /dev/null +++ b/js/src/jit-test/tests/function/function-displayName-computed.js @@ -0,0 +1,69 @@ +// |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</<"); 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()"); |