tor-browser

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

function-toString-discard-source.js (5401B)


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