| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 class ClassStubGenerator { | 7 class ClassStubGenerator { |
| 8 final Namer namer; | 8 final Namer namer; |
| 9 final Compiler compiler; | 9 final Compiler compiler; |
| 10 final JavaScriptBackend backend; | 10 final JavaScriptBackend backend; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 jsAst.Expression function; | 180 jsAst.Expression function; |
| 181 if (backend.isInterceptedName(selector.name)) { | 181 if (backend.isInterceptedName(selector.name)) { |
| 182 function = js(r'function($receiver, #) { return # }', | 182 function = js(r'function($receiver, #) { return # }', |
| 183 [parameterNames, expression]); | 183 [parameterNames, expression]); |
| 184 } else { | 184 } else { |
| 185 function = js(r'function(#) { return # }', [parameterNames, expression]); | 185 function = js(r'function(#) { return # }', [parameterNames, expression]); |
| 186 } | 186 } |
| 187 return new StubMethod(name, function); | 187 return new StubMethod(name, function); |
| 188 } | 188 } |
| 189 } | 189 } |
| 190 |
| 191 /// Creates two JavaScript functions: `tearOffGetter` and `tearOff`. |
| 192 /// |
| 193 /// `tearOffGetter` is internal and only used by `tearOff`. |
| 194 /// |
| 195 /// `tearOff` takes the following arguments: |
| 196 /// * `funcs`: a list of functions. These are the functions representing the |
| 197 /// member that is torn off. There can be more than one, since a member |
| 198 /// can have several stubs. |
| 199 /// Each function must have the `$callName` property set. |
| 200 /// * `reflectionInfo`: contains reflective information, and the function |
| 201 /// type. TODO(floitsch): point to where this is specified. |
| 202 /// * `isStatic`. |
| 203 /// * `name`. |
| 204 /// * `isIntercepted. |
| 205 List<jsAst.Statement> buildTearOffCode(JavaScriptBackend backend) { |
| 206 Namer namer = backend.namer; |
| 207 Compiler compiler = backend.compiler; |
| 208 |
| 209 Element closureFromTearOff = backend.findHelper('closureFromTearOff'); |
| 210 String tearOffAccessText; |
| 211 jsAst.Expression tearOffAccessExpression; |
| 212 String tearOffGlobalObjectName; |
| 213 String tearOffGlobalObject; |
| 214 if (closureFromTearOff != null) { |
| 215 // We need both the AST that references [closureFromTearOff] and a string |
| 216 // for the NoCsp version that constructs a function. |
| 217 tearOffAccessExpression = |
| 218 backend.emitter.staticFunctionAccess(closureFromTearOff); |
| 219 tearOffAccessText = |
| 220 jsAst.prettyPrint(tearOffAccessExpression, compiler).getText(); |
| 221 tearOffGlobalObjectName = tearOffGlobalObject = |
| 222 namer.globalObjectFor(closureFromTearOff); |
| 223 } else { |
| 224 // Default values for mocked-up test libraries. |
| 225 tearOffAccessText = |
| 226 r'''function() { throw 'Helper \'closureFromTearOff\' missing.' }'''; |
| 227 tearOffAccessExpression = js(tearOffAccessText); |
| 228 tearOffGlobalObjectName = 'MissingHelperFunction'; |
| 229 tearOffGlobalObject = '($tearOffAccessText())'; |
| 230 } |
| 231 |
| 232 jsAst.Statement tearOffGetter; |
| 233 if (!compiler.useContentSecurityPolicy) { |
| 234 // This template is uncached because it is constructed from code fragments |
| 235 // that can change from compilation to compilation. Some of these could be |
| 236 // avoided, except for the string literals that contain the compiled access |
| 237 // path to 'closureFromTearOff'. |
| 238 tearOffGetter = js.uncachedStatementTemplate(''' |
| 239 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { |
| 240 return isIntercepted |
| 241 ? new Function("funcs", "reflectionInfo", "name", |
| 242 "$tearOffGlobalObjectName", "c", |
| 243 "return function tearOff_" + name + (functionCounter++) + "(x) {" + |
| 244 "if (c === null) c = $tearOffAccessText(" + |
| 245 "this, funcs, reflectionInfo, false, [x], name);" + |
| 246 "return new c(this, funcs[0], x, name);" + |
| 247 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null) |
| 248 : new Function("funcs", "reflectionInfo", "name", |
| 249 "$tearOffGlobalObjectName", "c", |
| 250 "return function tearOff_" + name + (functionCounter++)+ "() {" + |
| 251 "if (c === null) c = $tearOffAccessText(" + |
| 252 "this, funcs, reflectionInfo, false, [], name);" + |
| 253 "return new c(this, funcs[0], null, name);" + |
| 254 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null); |
| 255 }''').instantiate([]); |
| 256 } else { |
| 257 tearOffGetter = js.statement(''' |
| 258 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { |
| 259 var cache = null; |
| 260 return isIntercepted |
| 261 ? function(x) { |
| 262 if (cache === null) cache = #( |
| 263 this, funcs, reflectionInfo, false, [x], name); |
| 264 return new cache(this, funcs[0], x, name); |
| 265 } |
| 266 : function() { |
| 267 if (cache === null) cache = #( |
| 268 this, funcs, reflectionInfo, false, [], name); |
| 269 return new cache(this, funcs[0], null, name); |
| 270 }; |
| 271 }''', [tearOffAccessExpression, tearOffAccessExpression]); |
| 272 } |
| 273 |
| 274 jsAst.Statement tearOff = js.statement(''' |
| 275 function tearOff(funcs, reflectionInfo, isStatic, name, isIntercepted) { |
| 276 var cache; |
| 277 return isStatic |
| 278 ? function() { |
| 279 if (cache === void 0) cache = #tearOff( |
| 280 this, funcs, reflectionInfo, true, [], name).prototype; |
| 281 return cache; |
| 282 } |
| 283 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); |
| 284 }''', {'tearOff': tearOffAccessExpression}); |
| 285 |
| 286 return <jsAst.Statement>[tearOffGetter, tearOff]; |
| 287 } |
| OLD | NEW |