| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 // TODO(ahe): Share these with js_helper.dart. | 7 // TODO(ahe): Share these with js_helper.dart. |
| 8 const FUNCTION_INDEX = 0; | 8 const FUNCTION_INDEX = 0; |
| 9 const NAME_INDEX = 1; | 9 const NAME_INDEX = 1; |
| 10 const CALL_NAME_INDEX = 2; | 10 const CALL_NAME_INDEX = 2; |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 if (optionalParameterCount) descriptor[unmangledName + "*"] = funcs[0]; | 220 if (optionalParameterCount) descriptor[unmangledName + "*"] = funcs[0]; |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 ''', [globalFunctionsAccess, interceptedNamesAccess, | 223 ''', [globalFunctionsAccess, interceptedNamesAccess, |
| 224 mangledGlobalNamesAccess, mangledNamesAccess]); | 224 mangledGlobalNamesAccess, mangledNamesAccess]); |
| 225 | 225 |
| 226 List<jsAst.Statement> tearOffCode = buildTearOffCode(backend); | 226 List<jsAst.Statement> tearOffCode = buildTearOffCode(backend); |
| 227 | 227 |
| 228 jsAst.Statement init = js.statement('''{ | 228 jsAst.Statement init = js.statement('''{ |
| 229 var functionCounter = 0; | 229 var functionCounter = 0; |
| 230 var tearOffGetter = (typeof dart_precompiled == "function") | |
| 231 ? tearOffGetterCsp : tearOffGetterNoCsp; | |
| 232 if (!#) # = []; // embedded libraries. | 230 if (!#) # = []; // embedded libraries. |
| 233 if (!#) # = map(); // embedded mangledNames. | 231 if (!#) # = map(); // embedded mangledNames. |
| 234 if (!#) # = map(); // embedded mangledGlobalNames. | 232 if (!#) # = map(); // embedded mangledGlobalNames. |
| 235 if (!#) # = map(); // embedded statics. | 233 if (!#) # = map(); // embedded statics. |
| 236 if (!#) # = map(); // embedded typeInformation. | 234 if (!#) # = map(); // embedded typeInformation. |
| 237 if (!#) # = map(); // embedded globalFunctions. | 235 if (!#) # = map(); // embedded globalFunctions. |
| 238 if (!#) # = map(); // embedded interceptedNames. | 236 if (!#) # = map(); // embedded interceptedNames. |
| 239 var libraries = #; // embeded libraries. | 237 var libraries = #; // embeded libraries. |
| 240 var mangledNames = #; // embedded mangledNames. | 238 var mangledNames = #; // embedded mangledNames. |
| 241 var mangledGlobalNames = #; // embedded mangledGlobalNames. | 239 var mangledGlobalNames = #; // embedded mangledGlobalNames. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 namer.globalObjectFor(closureFromTearOff); | 324 namer.globalObjectFor(closureFromTearOff); |
| 327 } else { | 325 } else { |
| 328 // Default values for mocked-up test libraries. | 326 // Default values for mocked-up test libraries. |
| 329 tearOffAccessText = | 327 tearOffAccessText = |
| 330 r'''function() { throw 'Helper \'closureFromTearOff\' missing.' }'''; | 328 r'''function() { throw 'Helper \'closureFromTearOff\' missing.' }'''; |
| 331 tearOffAccessExpression = js(tearOffAccessText); | 329 tearOffAccessExpression = js(tearOffAccessText); |
| 332 tearOffGlobalObjectName = 'MissingHelperFunction'; | 330 tearOffGlobalObjectName = 'MissingHelperFunction'; |
| 333 tearOffGlobalObject = '($tearOffAccessText())'; | 331 tearOffGlobalObject = '($tearOffAccessText())'; |
| 334 } | 332 } |
| 335 | 333 |
| 336 // This template is uncached because it is constructed from code fragments | 334 jsAst.Statement tearOffGetter; |
| 337 // that can change from compilation to compilation. Some of these could be | 335 if (!compiler.useContentSecurityPolicy) { |
| 338 // avoided, except for the string literals that contain the compiled access | 336 // This template is uncached because it is constructed from code fragments |
| 339 // path to 'closureFromTearOff'. | 337 // that can change from compilation to compilation. Some of these could be |
| 340 jsAst.Statement tearOffGetterNoCsp = js.uncachedStatementTemplate(''' | 338 // avoided, except for the string literals that contain the compiled access |
| 341 function tearOffGetterNoCsp(funcs, reflectionInfo, name, isIntercepted) { | 339 // path to 'closureFromTearOff'. |
| 342 return isIntercepted | 340 tearOffGetter = js.uncachedStatementTemplate(''' |
| 343 ? new Function("funcs", "reflectionInfo", "name", | 341 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { |
| 344 "$tearOffGlobalObjectName", "c", | 342 return isIntercepted |
| 345 "return function tearOff_" + name + (functionCounter++)+ "(x) {" + | 343 ? new Function("funcs", "reflectionInfo", "name", |
| 346 "if (c === null) c = $tearOffAccessText(" + | 344 "$tearOffGlobalObjectName", "c", |
| 347 "this, funcs, reflectionInfo, false, [x], name);" + | 345 "return function tearOff_" + name + (functionCounter++)+ "(x)
{" + |
| 348 "return new c(this, funcs[0], x, name);" + | 346 "if (c === null) c = $tearOffAccessText(" + |
| 349 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null) | 347 "this, funcs, reflectionInfo, false, [x], name);" + |
| 350 : new Function("funcs", "reflectionInfo", "name", | 348 "return new c(this, funcs[0], x, name);" + |
| 351 "$tearOffGlobalObjectName", "c", | 349 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null) |
| 352 "return function tearOff_" + name + (functionCounter++)+ "() {" + | 350 : new Function("funcs", "reflectionInfo", "name", |
| 353 "if (c === null) c = $tearOffAccessText(" + | 351 "$tearOffGlobalObjectName", "c", |
| 354 "this, funcs, reflectionInfo, false, [], name);" + | 352 "return function tearOff_" + name + (functionCounter++)+ "() {
" + |
| 355 "return new c(this, funcs[0], null, name);" + | 353 "if (c === null) c = $tearOffAccessText(" + |
| 356 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null); | 354 "this, funcs, reflectionInfo, false, [], name);" + |
| 357 }''').instantiate([]); | 355 "return new c(this, funcs[0], null, name);" + |
| 358 | 356 "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null); |
| 359 jsAst.Statement tearOffGetterCsp = js.statement(''' | 357 }''').instantiate([]); |
| 360 function tearOffGetterCsp(funcs, reflectionInfo, name, isIntercepted) { | 358 } else { |
| 361 var cache = null; | 359 tearOffGetter = js.statement(''' |
| 362 return isIntercepted | 360 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { |
| 363 ? function(x) { | 361 var cache = null; |
| 364 if (cache === null) cache = #( | 362 return isIntercepted |
| 365 this, funcs, reflectionInfo, false, [x], name); | 363 ? function(x) { |
| 366 return new cache(this, funcs[0], x, name); | 364 if (cache === null) cache = #( |
| 367 } | 365 this, funcs, reflectionInfo, false, [x], name); |
| 368 : function() { | 366 return new cache(this, funcs[0], x, name); |
| 369 if (cache === null) cache = #( | 367 } |
| 370 this, funcs, reflectionInfo, false, [], name); | 368 : function() { |
| 371 return new cache(this, funcs[0], null, name); | 369 if (cache === null) cache = #( |
| 372 }; | 370 this, funcs, reflectionInfo, false, [], name); |
| 373 }''', [tearOffAccessExpression, tearOffAccessExpression]); | 371 return new cache(this, funcs[0], null, name); |
| 372 }; |
| 373 }''', [tearOffAccessExpression, tearOffAccessExpression]); |
| 374 } |
| 374 | 375 |
| 375 jsAst.Statement tearOff = js.statement(''' | 376 jsAst.Statement tearOff = js.statement(''' |
| 376 function tearOff(funcs, reflectionInfo, isStatic, name, isIntercepted) { | 377 function tearOff(funcs, reflectionInfo, isStatic, name, isIntercepted) { |
| 377 var cache; | 378 var cache; |
| 378 return isStatic | 379 return isStatic |
| 379 ? function() { | 380 ? function() { |
| 380 if (cache === void 0) cache = #( | 381 if (cache === void 0) cache = #( |
| 381 this, funcs, reflectionInfo, true, [], name).prototype; | 382 this, funcs, reflectionInfo, true, [], name).prototype; |
| 382 return cache; | 383 return cache; |
| 383 } | 384 } |
| 384 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); | 385 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); |
| 385 }''', tearOffAccessExpression); | 386 }''', tearOffAccessExpression); |
| 386 | 387 |
| 387 return <jsAst.Statement>[tearOffGetterNoCsp, tearOffGetterCsp, tearOff]; | 388 return <jsAst.Statement>[tearOffGetter, tearOff]; |
| 388 } | 389 } |
| 389 | 390 |
| 390 | |
| 391 String readString(String array, String index) { | 391 String readString(String array, String index) { |
| 392 return readChecked( | 392 return readChecked( |
| 393 array, index, 'result != null && typeof result != "string"', 'string'); | 393 array, index, 'result != null && typeof result != "string"', 'string'); |
| 394 } | 394 } |
| 395 | 395 |
| 396 String readInt(String array, String index) { | 396 String readInt(String array, String index) { |
| 397 return readChecked( | 397 return readChecked( |
| 398 array, index, | 398 array, index, |
| 399 'result != null && (typeof result != "number" || (result|0) !== result)', | 399 'result != null && (typeof result != "number" || (result|0) !== result)', |
| 400 'int'); | 400 'int'); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 415 (function() { | 415 (function() { |
| 416 var result = $array[$index]; | 416 var result = $array[$index]; |
| 417 if ($check) { | 417 if ($check) { |
| 418 throw new Error( | 418 throw new Error( |
| 419 name + ": expected value of type \'$type\' at index " + ($index) + | 419 name + ": expected value of type \'$type\' at index " + ($index) + |
| 420 " but got " + (typeof result)); | 420 " but got " + (typeof result)); |
| 421 } | 421 } |
| 422 return result; | 422 return result; |
| 423 })()'''; | 423 })()'''; |
| 424 } | 424 } |
| OLD | NEW |