| 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 library dart2js.new_js_emitter.model_emitter; | 5 library dart2js.new_js_emitter.model_emitter; |
| 6 | 6 |
| 7 import '../../dart2jslib.dart' show Compiler; | 7 import '../../dart2jslib.dart' show Compiler; |
| 8 import '../../js/js.dart' as js; | 8 import '../../js/js.dart' as js; |
| 9 import '../../js_backend/js_backend.dart' show | 9 import '../../js_backend/js_backend.dart' show |
| 10 JavaScriptBackend, | 10 JavaScriptBackend, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 } | 71 } |
| 72 | 72 |
| 73 js.Statement emitMainUnit(Program program) { | 73 js.Statement emitMainUnit(Program program) { |
| 74 MainOutput unit = program.outputs.first; | 74 MainOutput unit = program.outputs.first; |
| 75 List<js.Expression> elements = unit.libraries.map(emitLibrary).toList(); | 75 List<js.Expression> elements = unit.libraries.map(emitLibrary).toList(); |
| 76 elements.add( | 76 elements.add( |
| 77 emitLazilyInitializedStatics(unit.staticLazilyInitializedFields)); | 77 emitLazilyInitializedStatics(unit.staticLazilyInitializedFields)); |
| 78 js.Expression code = new js.ArrayInitializer.from(elements); | 78 js.Expression code = new js.ArrayInitializer.from(elements); |
| 79 return js.js.statement( | 79 return js.js.statement( |
| 80 boilerplate, | 80 boilerplate, |
| 81 [emitDeferredInitializerGlobal(program.loadMap), | 81 {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap), |
| 82 emitHolders(unit.holders), | 82 'holders': emitHolders(unit.holders), |
| 83 namer.elementAccess(backend.getCyclicThrowHelper()), | 83 'cyclicThrow': namer.elementAccess(backend.getCyclicThrowHelper()), |
| 84 program.outputContainsConstantList, | 84 'outputContainsConstantList': program.outputContainsConstantList, |
| 85 emitEmbeddedGlobals(program.loadMap), | 85 'embeddedGlobals': emitEmbeddedGlobals(program.loadMap), |
| 86 emitConstants(unit.constants), | 86 'constants': emitConstants(unit.constants), |
| 87 emitStaticNonFinalFields(unit.staticNonFinalFields), | 87 'staticNonFinals': emitStaticNonFinalFields(unit.staticNonFinalFields), |
| 88 emitEagerClassInitializations(unit.libraries), | 88 'eagerClasses': emitEagerClassInitializations(unit.libraries), |
| 89 unit.main, | 89 'main': unit.main, |
| 90 code]); | 90 'code': code}); |
| 91 } | 91 } |
| 92 | 92 |
| 93 js.Block emitHolders(List<Holder> holders) { | 93 js.Block emitHolders(List<Holder> holders) { |
| 94 // The top-level variables for holders must *not* be renamed by the | 94 // The top-level variables for holders must *not* be renamed by the |
| 95 // JavaScript pretty printer because a lot of code already uses the | 95 // JavaScript pretty printer because a lot of code already uses the |
| 96 // non-renamed names. The generated code looks like this: | 96 // non-renamed names. The generated code looks like this: |
| 97 // | 97 // |
| 98 // var H = {}, ..., G = {}; | 98 // var H = {}, ..., G = {}; |
| 99 // var holders = [ H, ..., G ]; | 99 // var holders = [ H, ..., G ]; |
| 100 // | 100 // |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 return unparse(compiler, field.code); | 355 return unparse(compiler, field.code); |
| 356 } | 356 } |
| 357 | 357 |
| 358 js.Expression emitStaticMethod(StaticMethod method) { | 358 js.Expression emitStaticMethod(StaticMethod method) { |
| 359 return unparse(compiler, method.code); | 359 return unparse(compiler, method.code); |
| 360 } | 360 } |
| 361 | 361 |
| 362 static final String boilerplate = """ | 362 static final String boilerplate = """ |
| 363 { | 363 { |
| 364 // Declare deferred-initializer global. | 364 // Declare deferred-initializer global. |
| 365 #; | 365 #deferredInitializer; |
| 366 | 366 |
| 367 !function(start, program) { | 367 !function(start, program) { |
| 368 | 368 |
| 369 // Initialize holder objects. | 369 // Initialize holder objects. |
| 370 #; | 370 #holders; |
| 371 | 371 |
| 372 function setupProgram() { | 372 function setupProgram() { |
| 373 for (var i = 0; i < program.length - 1; i++) { | 373 for (var i = 0; i < program.length - 1; i++) { |
| 374 setupLibrary(program[i]); | 374 setupLibrary(program[i]); |
| 375 } | 375 } |
| 376 setupLazyStatics(program[i]); | 376 setupLazyStatics(program[i]); |
| 377 } | 377 } |
| 378 | 378 |
| 379 function setupLibrary(library) { | 379 function setupLibrary(library) { |
| 380 var statics = library[0]; | 380 var statics = library[0]; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 405 var method = compile(name, descriptor); | 405 var method = compile(name, descriptor); |
| 406 holder[name] = method; | 406 holder[name] = method; |
| 407 return method.apply(this, arguments); | 407 return method.apply(this, arguments); |
| 408 }; | 408 }; |
| 409 } | 409 } |
| 410 | 410 |
| 411 function setupLazyStatic(name, getterName, holder, descriptor) { | 411 function setupLazyStatic(name, getterName, holder, descriptor) { |
| 412 holder[name] = null; | 412 holder[name] = null; |
| 413 holder[getterName] = function() { | 413 holder[getterName] = function() { |
| 414 var initializer = compile(name, descriptor); | 414 var initializer = compile(name, descriptor); |
| 415 holder[getterName] = function() { #(name) }; // cyclicThrowHelper | 415 holder[getterName] = function() { #cyclicThrow(name) }; |
| 416 var result; | 416 var result; |
| 417 var sentinelInProgress = descriptor; | 417 var sentinelInProgress = descriptor; |
| 418 try { | 418 try { |
| 419 result = holder[name] = sentinelInProgress; | 419 result = holder[name] = sentinelInProgress; |
| 420 result = holder[name] = initializer(); | 420 result = holder[name] = initializer(); |
| 421 } finally { | 421 } finally { |
| 422 // Use try-finally, not try-catch/throw as it destroys the stack trace. | 422 // Use try-finally, not try-catch/throw as it destroys the stack trace. |
| 423 if (result === sentinelInProgress) { | 423 if (result === sentinelInProgress) { |
| 424 // The lazy static (holder[name]) might have been set to a different | 424 // The lazy static (holder[name]) might have been set to a different |
| 425 // value. According to spec we still have to reset it to null, if the | 425 // value. According to spec we still have to reset it to null, if the |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 return new intermediate(); | 505 return new intermediate(); |
| 506 } | 506 } |
| 507 | 507 |
| 508 function compile(__name__, __s__) { | 508 function compile(__name__, __s__) { |
| 509 'use strict'; | 509 'use strict'; |
| 510 // TODO(floitsch): evaluate the performance impact of the string | 510 // TODO(floitsch): evaluate the performance impact of the string |
| 511 // concatenations. | 511 // concatenations. |
| 512 return eval(__s__ + "\\n//# sourceURL=" + __name__ + ".js"); | 512 return eval(__s__ + "\\n//# sourceURL=" + __name__ + ".js"); |
| 513 } | 513 } |
| 514 | 514 |
| 515 if (#) { // outputContainsConstantList | 515 if (#outputContainsConstantList) { |
| 516 function makeConstList(list) { | 516 function makeConstList(list) { |
| 517 // By assigning a function to the properties they become part of the | 517 // By assigning a function to the properties they become part of the |
| 518 // hidden class. The actual values of the fields don't matter, since we | 518 // hidden class. The actual values of the fields don't matter, since we |
| 519 // only check if they exist. | 519 // only check if they exist. |
| 520 list.immutable\$list = Array; | 520 list.immutable\$list = Array; |
| 521 list.fixed\$length = Array; | 521 list.fixed\$length = Array; |
| 522 return list; | 522 return list; |
| 523 } | 523 } |
| 524 } | 524 } |
| 525 | 525 |
| 526 setupProgram(); | 526 setupProgram(); |
| 527 | 527 |
| 528 // Initialize globals. | 528 // Initialize globals. |
| 529 #; | 529 #embeddedGlobals; |
| 530 | 530 |
| 531 // Initialize constants. | 531 // Initialize constants. |
| 532 #; | 532 #constants; |
| 533 | 533 |
| 534 // Initialize static non-final fields. | 534 // Initialize static non-final fields. |
| 535 #; | 535 #staticNonFinals; |
| 536 | 536 |
| 537 // Initialize eager classes. | 537 // Initialize eager classes. |
| 538 #; | 538 #eagerClasses; |
| 539 | 539 |
| 540 var end = Date.now(); | 540 var end = Date.now(); |
| 541 print('Setup: ' + (end - start) + ' ms.'); | 541 print('Setup: ' + (end - start) + ' ms.'); |
| 542 | 542 |
| 543 if (true) #(); // Start main. | 543 #main(); // Start main. |
| 544 | 544 |
| 545 }(Date.now(), #) | 545 }(Date.now(), #code) |
| 546 }"""; | 546 }"""; |
| 547 | 547 |
| 548 } | 548 } |
| OLD | NEW |