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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 /// * `reflectionInfo`: contains reflective information, and the function | 213 /// * `reflectionInfo`: contains reflective information, and the function |
214 /// type. TODO(floitsch): point to where this is specified. | 214 /// type. TODO(floitsch): point to where this is specified. |
215 /// * `isStatic`. | 215 /// * `isStatic`. |
216 /// * `name`. | 216 /// * `name`. |
217 /// * `isIntercepted. | 217 /// * `isIntercepted. |
218 List<jsAst.Statement> buildTearOffCode(JavaScriptBackend backend) { | 218 List<jsAst.Statement> buildTearOffCode(JavaScriptBackend backend) { |
219 Namer namer = backend.namer; | 219 Namer namer = backend.namer; |
220 Compiler compiler = backend.compiler; | 220 Compiler compiler = backend.compiler; |
221 | 221 |
222 Element closureFromTearOff = backend.findHelper('closureFromTearOff'); | 222 Element closureFromTearOff = backend.findHelper('closureFromTearOff'); |
223 String tearOffAccessText; | |
224 jsAst.Expression tearOffAccessExpression; | 223 jsAst.Expression tearOffAccessExpression; |
225 String tearOffGlobalObjectName; | 224 jsAst.Expression tearOffGlobalObjectString; |
226 String tearOffGlobalObject; | 225 jsAst.Expression tearOffGlobalObject; |
227 if (closureFromTearOff != null) { | 226 if (closureFromTearOff != null) { |
228 // We need both the AST that references [closureFromTearOff] and a string | |
229 // for the NoCsp version that constructs a function. | |
230 tearOffAccessExpression = | 227 tearOffAccessExpression = |
231 backend.emitter.staticFunctionAccess(closureFromTearOff); | 228 backend.emitter.staticFunctionAccess(closureFromTearOff); |
232 tearOffAccessText = | 229 tearOffGlobalObject = |
233 jsAst.prettyPrint(tearOffAccessExpression, compiler).getText(); | 230 js.stringPart(namer.globalObjectFor(closureFromTearOff)); |
234 tearOffGlobalObjectName = tearOffGlobalObject = | 231 tearOffGlobalObjectString = |
235 namer.globalObjectFor(closureFromTearOff); | 232 js.string(namer.globalObjectFor(closureFromTearOff)); |
236 } else { | 233 } else { |
237 // Default values for mocked-up test libraries. | 234 // Default values for mocked-up test libraries. |
238 tearOffAccessText = | 235 tearOffAccessExpression = js( |
239 r'''function() { throw "Helper 'closureFromTearOff' missing." }'''; | 236 r'''function() { throw "Helper 'closureFromTearOff' missing." }'''); |
240 tearOffAccessExpression = js(tearOffAccessText); | 237 tearOffGlobalObjectString = js.string('MissingHelperFunction'); |
241 tearOffGlobalObjectName = 'MissingHelperFunction'; | 238 tearOffGlobalObject = js( |
242 tearOffGlobalObject = '($tearOffAccessText())'; | 239 r'''(function() { throw "Helper 'closureFromTearOff' missing." })()'''); |
243 } | 240 } |
244 | 241 |
245 jsAst.Statement tearOffGetter; | 242 jsAst.Statement tearOffGetter; |
246 if (!compiler.useContentSecurityPolicy) { | 243 if (!compiler.useContentSecurityPolicy) { |
247 // This template is uncached because it is constructed from code fragments | 244 jsAst.Expression tearOffAccessText = |
248 // that can change from compilation to compilation. Some of these could be | 245 new jsAst.UnparsedNode(tearOffAccessExpression, compiler, false); |
249 // avoided, except for the string literals that contain the compiled access | 246 tearOffGetter = js.statement(''' |
250 // path to 'closureFromTearOff'. | |
251 tearOffGetter = js.uncachedStatementTemplate(''' | |
252 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { | 247 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { |
253 return isIntercepted | 248 return isIntercepted |
254 ? new Function("funcs", "reflectionInfo", "name", | 249 ? new Function("funcs", "reflectionInfo", "name", |
255 "$tearOffGlobalObjectName", "c", | 250 #tearOffGlobalObjectString, "c", |
256 "return function tearOff_" + name + (functionCounter++) + "(x) {" + | 251 "return function tearOff_" + name + (functionCounter++) + "(x) {" + |
257 "if (c === null) c = $tearOffAccessText(" + | 252 "if (c === null) c = " + #tearOffAccessText + "(" + |
258 "this, funcs, reflectionInfo, false, [x], name);" + | 253 "this, funcs, reflectionInfo, false, [x], name);" + |
259 "return new c(this, funcs[0], x, name);" + | 254 "return new c(this, funcs[0], x, name);" + |
260 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null) | 255 "}")(funcs, reflectionInfo, name, #tearOffGlobalObject, null) |
261 : new Function("funcs", "reflectionInfo", "name", | 256 : new Function("funcs", "reflectionInfo", "name", |
262 "$tearOffGlobalObjectName", "c", | 257 #tearOffGlobalObjectString, "c", |
263 "return function tearOff_" + name + (functionCounter++)+ "() {" + | 258 "return function tearOff_" + name + (functionCounter++)+ "() {" + |
264 "if (c === null) c = $tearOffAccessText(" + | 259 "if (c === null) c = " + #tearOffAccessText + "(" + |
265 "this, funcs, reflectionInfo, false, [], name);" + | 260 "this, funcs, reflectionInfo, false, [], name);" + |
266 "return new c(this, funcs[0], null, name);" + | 261 "return new c(this, funcs[0], null, name);" + |
267 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null); | 262 "}")(funcs, reflectionInfo, name, #tearOffGlobalObject, null); |
268 }''').instantiate([]); | 263 }''', {'tearOffAccessText': tearOffAccessText, |
| 264 'tearOffGlobalObject': tearOffGlobalObject, |
| 265 'tearOffGlobalObjectString': tearOffGlobalObjectString}); |
269 } else { | 266 } else { |
270 tearOffGetter = js.statement(''' | 267 tearOffGetter = js.statement(''' |
271 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { | 268 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { |
272 var cache = null; | 269 var cache = null; |
273 return isIntercepted | 270 return isIntercepted |
274 ? function(x) { | 271 ? function(x) { |
275 if (cache === null) cache = #( | 272 if (cache === null) cache = #( |
276 this, funcs, reflectionInfo, false, [x], name); | 273 this, funcs, reflectionInfo, false, [x], name); |
277 return new cache(this, funcs[0], x, name); | 274 return new cache(this, funcs[0], x, name); |
278 } | 275 } |
(...skipping 12 matching lines...) Expand all Loading... |
291 ? function() { | 288 ? function() { |
292 if (cache === void 0) cache = #tearOff( | 289 if (cache === void 0) cache = #tearOff( |
293 this, funcs, reflectionInfo, true, [], name).prototype; | 290 this, funcs, reflectionInfo, true, [], name).prototype; |
294 return cache; | 291 return cache; |
295 } | 292 } |
296 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); | 293 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); |
297 }''', {'tearOff': tearOffAccessExpression}); | 294 }''', {'tearOff': tearOffAccessExpression}); |
298 | 295 |
299 return <jsAst.Statement>[tearOffGetter, tearOff]; | 296 return <jsAst.Statement>[tearOffGetter, tearOff]; |
300 } | 297 } |
OLD | NEW |