tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

function-toString-discard-source-name.js (5491B)


      1 // Repeats the test from 'function/function-toString-discard-source.js' and
      2 // additionally verifies the name matches the expected value.
      3 //
      4 // This behaviour is not required by the ECMAScript standard.
      5 
      6 // The Function.prototype.toString() representation of sourceless functions
      7 // must match the NativeFunction syntax.
      8 
      9 function test() {
     10 // Greatly (!) simplified patterns for the PropertyName production.
     11 var propertyName = [
     12    // PropertyName :: LiteralPropertyName :: IdentifierName
     13    "\\w+",
     14 
     15    // PropertyName :: LiteralPropertyName :: StringLiteral
     16    "(?:'[^']*')",
     17    "(?:\"[^\"]*\")",
     18 
     19    // PropertyName :: LiteralPropertyName :: NumericLiteral
     20    "\\d+",
     21 
     22    // PropertyName :: ComputedPropertyName
     23    "(?:\\[[^\\]]+\\])",
     24 ].join("|")
     25 
     26 var nativeCode = RegExp([
     27    "^", "function", ("(" + propertyName + ")?"), "\\(", "\\)", "\\{", "\\[native code\\]", "\\}", "$"
     28 ].join("\\s*"));
     29 
     30 function assertFunctionName(fun, expected) {
     31    var match = nativeCode.exec(fun.toString());
     32    assertEq(match[1], expected);
     33 }
     34 
     35 
     36 // Function declarations.
     37 
     38 eval(`
     39 function funDecl() {}
     40 function* genDecl() {}
     41 async function asyncFunDecl() {}
     42 async function* asyncGenDecl() {}
     43 `);
     44 
     45 assertFunctionName(funDecl, "funDecl");
     46 assertFunctionName(genDecl, "genDecl");
     47 assertFunctionName(asyncFunDecl, "asyncFunDecl");
     48 assertFunctionName(asyncGenDecl, "asyncGenDecl");
     49 
     50 
     51 // Named function expressions.
     52 
     53 eval(`
     54 var funExpr = function fn() {};
     55 var genExpr = function* fn() {};
     56 var asyncFunExpr = async function fn() {};
     57 var asyncGenExpr = async function* fn() {};
     58 `);
     59 
     60 assertFunctionName(funExpr, "fn");
     61 assertFunctionName(genExpr, "fn");
     62 assertFunctionName(asyncFunExpr, "fn");
     63 assertFunctionName(asyncGenExpr, "fn");
     64 
     65 
     66 // Anonymous function expressions.
     67 
     68 eval(`
     69 var funExprAnon = function() {};
     70 var genExprAnon = function*() {};
     71 var asyncFunExprAnon = async function() {};
     72 var asyncGenExprAnon = async function*() {};
     73 `);
     74 
     75 assertFunctionName(funExprAnon, undefined);
     76 assertFunctionName(genExprAnon, undefined);
     77 assertFunctionName(asyncFunExprAnon, undefined);
     78 assertFunctionName(asyncGenExprAnon, undefined);
     79 
     80 
     81 // Class declarations and expressions (implicit constructor).
     82 eval(`
     83 class classDecl {}
     84 var classExpr = class C {};
     85 var classExprAnon = class {};
     86 var classExprAnonField = class {x = 1};
     87 
     88 this.classDecl = classDecl;
     89 `);
     90 
     91 assertFunctionName(classDecl, "classDecl");
     92 assertFunctionName(classExpr, "C");
     93 assertFunctionName(classExprAnon, undefined);
     94 assertFunctionName(classExprAnonField, undefined);
     95 
     96 
     97 // Class declarations and expressions (explicit constructor).
     98 eval(`
     99 class classDecl { constructor() {} }
    100 var classExpr = class C { constructor() {} };
    101 var classExprAnon = class { constructor() {} };
    102 
    103 this.classDecl = classDecl;
    104 `);
    105 
    106 assertFunctionName(classDecl, "classDecl");
    107 assertFunctionName(classExpr, "C");
    108 assertFunctionName(classExprAnon, undefined);
    109 
    110 
    111 // Method definitions (identifier names).
    112 eval(`
    113 var obj = {
    114   m() {},
    115   *gm() {},
    116   async am() {},
    117   async* agm() {},
    118   get x() {},
    119   set x(_) {},
    120 };
    121 `);
    122 
    123 assertFunctionName(obj.m, undefined);
    124 assertFunctionName(obj.gm, undefined);
    125 assertFunctionName(obj.am, undefined);
    126 assertFunctionName(obj.agm, undefined);
    127 assertFunctionName(Object.getOwnPropertyDescriptor(obj, "x").get, undefined);
    128 assertFunctionName(Object.getOwnPropertyDescriptor(obj, "x").set, undefined);
    129 
    130 
    131 // Method definitions (string names).
    132 eval(`
    133 var obj = {
    134    "foo m"() {},
    135    * "foo gm"() {},
    136    async "foo am"() {},
    137    async* "foo agm"() {},
    138    get "foo x"() {},
    139    set "foo x"(_) {},
    140 };
    141 `);
    142 
    143 assertFunctionName(obj["foo m"], undefined);
    144 assertFunctionName(obj["foo gm"], undefined);
    145 assertFunctionName(obj["foo am"], undefined);
    146 assertFunctionName(obj["foo agm"], undefined);
    147 assertFunctionName(Object.getOwnPropertyDescriptor(obj, "foo x").get, undefined);
    148 assertFunctionName(Object.getOwnPropertyDescriptor(obj, "foo x").set, undefined);
    149 
    150 
    151 // Method definitions (number names).
    152 eval(`
    153 var obj = {
    154    100() {},
    155    *200() {},
    156    async 300() {},
    157    async* 400() {},
    158    get 500() {},
    159    set 500(_) {},
    160 };
    161 `);
    162 
    163 assertFunctionName(obj[100], undefined);
    164 assertFunctionName(obj[200], undefined);
    165 assertFunctionName(obj[300], undefined);
    166 assertFunctionName(obj[400], undefined);
    167 assertFunctionName(Object.getOwnPropertyDescriptor(obj, 500).get, undefined);
    168 assertFunctionName(Object.getOwnPropertyDescriptor(obj, 500).set, undefined);
    169 
    170 
    171 // Method definitions (computed property names).
    172 
    173 var sym1 = Symbol();
    174 var sym2 = Symbol("desc");
    175 var sym3 = Symbol.for("reg-sym");
    176 var sym4 = Symbol.match;
    177 var sym5 = Symbol();
    178 
    179 eval(`
    180 var obj = {
    181    [sym1]() {},
    182    *[sym2]() {},
    183    async [sym3]() {},
    184    async* [sym4]() {},
    185    get [sym5]() {},
    186    set [sym5](_) {},
    187 };
    188 `);
    189 
    190 assertFunctionName(obj[sym1], undefined);
    191 assertFunctionName(obj[sym2], undefined);
    192 assertFunctionName(obj[sym3], undefined);
    193 assertFunctionName(obj[sym4], undefined);
    194 assertFunctionName(Object.getOwnPropertyDescriptor(obj, sym5).get, undefined);
    195 assertFunctionName(Object.getOwnPropertyDescriptor(obj, sym5).set, undefined);
    196 
    197 
    198 // Arrow functions.
    199 eval(`
    200 var arrowFn = () => {};
    201 var asyncArrowFn = () => {};
    202 `);
    203 
    204 assertFunctionName(arrowFn, undefined);
    205 assertFunctionName(asyncArrowFn, undefined);
    206 
    207 
    208 // asm.js functions.
    209 eval(`
    210 function asm() {
    211  "use asm";
    212  function f(){ return 0|0; }
    213  return {f: f};
    214 }
    215 `);
    216 
    217 assertFunctionName(asm, "asm");
    218 assertFunctionName(asm().f, "f");
    219 }
    220 
    221 var g = newGlobal({ discardSource: true });
    222 g.evaluate(test.toString() + "test()");