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()");