| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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.startup_emitter.model_emitter; | 5 part of dart2js.js_emitter.startup_emitter.model_emitter; |
| 6 | 6 |
| 7 /// The name of the property that stores the tear-off getter on a static | 7 /// The name of the property that stores the tear-off getter on a static |
| 8 /// function. | 8 /// function. |
| 9 /// | 9 /// |
| 10 /// This property is only used when isolates are used. | 10 /// This property is only used when isolates are used. |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 // hidden class. The actual values of the fields don't matter, since we | 164 // hidden class. The actual values of the fields don't matter, since we |
| 165 // only check if they exist. | 165 // only check if they exist. |
| 166 list.immutable\$list = Array; | 166 list.immutable\$list = Array; |
| 167 list.fixed\$length = Array; | 167 list.fixed\$length = Array; |
| 168 return list; | 168 return list; |
| 169 } | 169 } |
| 170 | 170 |
| 171 function convertToFastObject(properties) { | 171 function convertToFastObject(properties) { |
| 172 // Create an instance that uses 'properties' as prototype. This should | 172 // Create an instance that uses 'properties' as prototype. This should |
| 173 // make 'properties' a fast object. | 173 // make 'properties' a fast object. |
| 174 function t() {}; | 174 function t() {} |
| 175 t.prototype = properties; | 175 t.prototype = properties; |
| 176 new t(); | 176 new t(); |
| 177 return properties; | 177 return properties; |
| 178 } | 178 } |
| 179 | 179 |
| 180 // This variable is used by the tearOffCode to guarantee unique functions per | 180 // This variable is used by the tearOffCode to guarantee unique functions per |
| 181 // tear-offs. | 181 // tear-offs. |
| 182 var functionCounter = 0; | 182 var functionCounter = 0; |
| 183 #tearOffCode; | 183 #tearOffCode; |
| 184 | 184 |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 Map<Holder, Map<js.Name, js.Expression>> holderCode = | 556 Map<Holder, Map<js.Name, js.Expression>> holderCode = |
| 557 <Holder, Map<js.Name, js.Expression>>{}; | 557 <Holder, Map<js.Name, js.Expression>>{}; |
| 558 | 558 |
| 559 for (Holder holder in holders) { | 559 for (Holder holder in holders) { |
| 560 holderCode[holder] = <js.Name, js.Expression>{}; | 560 holderCode[holder] = <js.Name, js.Expression>{}; |
| 561 } | 561 } |
| 562 | 562 |
| 563 for (Library library in fragment.libraries) { | 563 for (Library library in fragment.libraries) { |
| 564 for (StaticMethod method in library.statics) { | 564 for (StaticMethod method in library.statics) { |
| 565 assert(!method.holder.isStaticStateHolder); | 565 assert(!method.holder.isStaticStateHolder); |
| 566 holderCode[method.holder].addAll(emitStaticMethod(method)); | 566 var staticMethod = emitStaticMethod(method); |
| 567 if (compiler.options.dumpInfo) { |
| 568 for (var code in staticMethod.values) { |
| 569 compiler.dumpInfoTask.registerElementAst(method.element, code); |
| 570 compiler.dumpInfoTask.registerElementAst(library.element, code); |
| 571 } |
| 572 } |
| 573 holderCode[method.holder].addAll(staticMethod); |
| 567 } | 574 } |
| 568 for (Class cls in library.classes) { | 575 for (Class cls in library.classes) { |
| 569 assert(!cls.holder.isStaticStateHolder); | 576 assert(!cls.holder.isStaticStateHolder); |
| 570 holderCode[cls.holder][cls.name] = emitConstructor(cls); | 577 var constructor = emitConstructor(cls); |
| 578 compiler.dumpInfoTask.registerElementAst(cls.element, constructor); |
| 579 compiler.dumpInfoTask.registerElementAst(library.element, constructor); |
| 580 holderCode[cls.holder][cls.name] = constructor; |
| 571 } | 581 } |
| 572 } | 582 } |
| 573 | 583 |
| 574 js.VariableInitialization emitHolderInitialization(Holder holder) { | 584 js.VariableInitialization emitHolderInitialization(Holder holder) { |
| 575 List<js.Property> properties = <js.Property>[]; | 585 List<js.Property> properties = <js.Property>[]; |
| 576 holderCode[holder].forEach((js.Name key, js.Expression value) { | 586 holderCode[holder].forEach((js.Name key, js.Expression value) { |
| 577 properties.add(new js.Property(js.quoteName(key), value)); | 587 properties.add(new js.Property(js.quoteName(key), value)); |
| 578 }); | 588 }); |
| 579 | 589 |
| 580 return new js.VariableInitialization( | 590 return new js.VariableInitialization( |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 return js.js('function #(#) { # }', [name, fieldNames, assignments]); | 671 return js.js('function #(#) { # }', [name, fieldNames, assignments]); |
| 662 } | 672 } |
| 663 | 673 |
| 664 /// Emits the prototype-section of the fragment. | 674 /// Emits the prototype-section of the fragment. |
| 665 /// | 675 /// |
| 666 /// This section updates the prototype-property of all constructors in the | 676 /// This section updates the prototype-property of all constructors in the |
| 667 /// global holders. | 677 /// global holders. |
| 668 js.Statement emitPrototypes(Fragment fragment) { | 678 js.Statement emitPrototypes(Fragment fragment) { |
| 669 List<js.Statement> assignments = fragment.libraries | 679 List<js.Statement> assignments = fragment.libraries |
| 670 .expand((Library library) => library.classes) | 680 .expand((Library library) => library.classes) |
| 671 .map((Class cls) => js.js.statement( | 681 .map((Class cls) { |
| 672 '#.prototype = #;', [classReference(cls), emitPrototype(cls)])) | 682 var proto = js.js.statement( |
| 673 .toList(growable: false); | 683 '#.prototype = #;', [classReference(cls), emitPrototype(cls)]); |
| 684 compiler.dumpInfoTask.registerElementAst(cls.element, proto); |
| 685 compiler.dumpInfoTask.registerElementAst(cls.element.library, proto); |
| 686 return proto; |
| 687 }).toList(growable: false); |
| 674 | 688 |
| 675 return new js.Block(assignments); | 689 return new js.Block(assignments); |
| 676 } | 690 } |
| 677 | 691 |
| 678 /// Emits the prototype of the given class [cls]. | 692 /// Emits the prototype of the given class [cls]. |
| 679 /// | 693 /// |
| 680 /// The prototype is generated as object literal. Inheritance is ignored. | 694 /// The prototype is generated as object literal. Inheritance is ignored. |
| 681 /// | 695 /// |
| 682 /// The prototype also includes the `is-property` that every class must have. | 696 /// The prototype also includes the `is-property` that every class must have. |
| 683 // TODO(floitsch): we could avoid that property if we knew that it wasn't | 697 // TODO(floitsch): we could avoid that property if we knew that it wasn't |
| (...skipping 21 matching lines...) Expand all Loading... |
| 705 if (cls.superclass == null) { | 719 if (cls.superclass == null) { |
| 706 properties | 720 properties |
| 707 .add(new js.Property(js.string("constructor"), classReference(cls))); | 721 .add(new js.Property(js.string("constructor"), classReference(cls))); |
| 708 properties | 722 properties |
| 709 .add(new js.Property(namer.operatorIs(cls.element), js.number(1))); | 723 .add(new js.Property(namer.operatorIs(cls.element), js.number(1))); |
| 710 } | 724 } |
| 711 | 725 |
| 712 allMethods.forEach((Method method) { | 726 allMethods.forEach((Method method) { |
| 713 emitInstanceMethod(method) | 727 emitInstanceMethod(method) |
| 714 .forEach((js.Expression name, js.Expression code) { | 728 .forEach((js.Expression name, js.Expression code) { |
| 715 properties.add(new js.Property(name, code)); | 729 var prop = new js.Property(name, code); |
| 730 compiler.dumpInfoTask.registerElementAst(method.element, prop); |
| 731 properties.add(prop); |
| 716 }); | 732 }); |
| 717 }); | 733 }); |
| 718 | 734 |
| 719 return new js.ObjectInitializer(properties); | 735 return new js.ObjectInitializer(properties); |
| 720 } | 736 } |
| 721 | 737 |
| 722 /// Generates a getter for the given [field]. | 738 /// Generates a getter for the given [field]. |
| 723 Method generateGetter(Field field) { | 739 Method generateGetter(Field field) { |
| 724 assert(field.needsGetter); | 740 assert(field.needsGetter); |
| 725 | 741 |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 } | 1020 } |
| 1005 | 1021 |
| 1006 /// Emits the constants section. | 1022 /// Emits the constants section. |
| 1007 js.Statement emitConstants(Fragment fragment) { | 1023 js.Statement emitConstants(Fragment fragment) { |
| 1008 List<js.Statement> assignments = <js.Statement>[]; | 1024 List<js.Statement> assignments = <js.Statement>[]; |
| 1009 for (Constant constant in fragment.constants) { | 1025 for (Constant constant in fragment.constants) { |
| 1010 // TODO(floitsch): instead of just updating the constant holder, we should | 1026 // TODO(floitsch): instead of just updating the constant holder, we should |
| 1011 // find the constants that don't have any dependency on other constants | 1027 // find the constants that don't have any dependency on other constants |
| 1012 // and create an object-literal with them (and assign it to the | 1028 // and create an object-literal with them (and assign it to the |
| 1013 // constant-holder variable). | 1029 // constant-holder variable). |
| 1014 assignments.add(js.js.statement('#.# = #', [ | 1030 var assignment = js.js.statement('#.# = #', [ |
| 1015 constant.holder.name, | 1031 constant.holder.name, |
| 1016 constant.name, | 1032 constant.name, |
| 1017 constantEmitter.generate(constant.value) | 1033 constantEmitter.generate(constant.value) |
| 1018 ])); | 1034 ]); |
| 1035 compiler.dumpInfoTask.registerConstantAst(constant.value, assignment); |
| 1036 assignments.add(assignment); |
| 1019 } | 1037 } |
| 1020 return new js.Block(assignments); | 1038 return new js.Block(assignments); |
| 1021 } | 1039 } |
| 1022 | 1040 |
| 1023 /// Emits the static non-final fields section. | 1041 /// Emits the static non-final fields section. |
| 1024 /// | 1042 /// |
| 1025 /// This section initializes all static non-final fields that don't require | 1043 /// This section initializes all static non-final fields that don't require |
| 1026 /// an initializer. | 1044 /// an initializer. |
| 1027 js.Block emitStaticNonFinalFields(Fragment fragment) { | 1045 js.Block emitStaticNonFinalFields(Fragment fragment) { |
| 1028 List<StaticField> fields = fragment.staticNonFinalFields; | 1046 List<StaticField> fields = fragment.staticNonFinalFields; |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 } | 1383 } |
| 1366 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", | 1384 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", |
| 1367 js.objectLiteral(interceptorsByTag))); | 1385 js.objectLiteral(interceptorsByTag))); |
| 1368 statements.add( | 1386 statements.add( |
| 1369 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); | 1387 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); |
| 1370 statements.addAll(subclassAssignments); | 1388 statements.addAll(subclassAssignments); |
| 1371 | 1389 |
| 1372 return new js.Block(statements); | 1390 return new js.Block(statements); |
| 1373 } | 1391 } |
| 1374 } | 1392 } |
| OLD | NEW |