| 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.js_emitter.program_builder; | 5 library dart2js.js_emitter.program_builder; |
| 6 | 6 |
| 7 import '../js_emitter.dart' show | 7 import '../js_emitter.dart' show |
| 8 ClassStubGenerator, | 8 ClassStubGenerator, |
| 9 CodeEmitterTask, | 9 CodeEmitterTask, |
| 10 computeMixinClass, | 10 computeMixinClass, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 FieldElement, | 38 FieldElement, |
| 39 FunctionElement, | 39 FunctionElement, |
| 40 FunctionSignature, | 40 FunctionSignature, |
| 41 LibraryElement, | 41 LibraryElement, |
| 42 MethodElement, | 42 MethodElement, |
| 43 Name, | 43 Name, |
| 44 ParameterElement, | 44 ParameterElement, |
| 45 TypedefElement, | 45 TypedefElement, |
| 46 VariableElement; | 46 VariableElement; |
| 47 import '../../js/js.dart' as js; | 47 import '../../js/js.dart' as js; |
| 48 import '../../js_backend/backend_helpers.dart' show |
| 49 BackendHelpers; |
| 48 import '../../js_backend/js_backend.dart' show | 50 import '../../js_backend/js_backend.dart' show |
| 49 Namer, | 51 Namer, |
| 50 JavaScriptBackend, | 52 JavaScriptBackend, |
| 51 JavaScriptConstantCompiler, | 53 JavaScriptConstantCompiler, |
| 52 StringBackedName; | 54 StringBackedName; |
| 53 import '../../universe/selector.dart' show | 55 import '../../universe/selector.dart' show |
| 54 Selector; | 56 Selector; |
| 55 import '../../universe/universe.dart' show | 57 import '../../universe/universe.dart' show |
| 56 Universe, | 58 Universe, |
| 57 SelectorConstraints; | 59 SelectorConstraints; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 87 this._task, | 89 this._task, |
| 88 Emitter emitter, | 90 Emitter emitter, |
| 89 Set<ClassElement> rtiNeededClasses) | 91 Set<ClassElement> rtiNeededClasses) |
| 90 : this._compiler = compiler, | 92 : this._compiler = compiler, |
| 91 this.namer = namer, | 93 this.namer = namer, |
| 92 this.collector = | 94 this.collector = |
| 93 new Collector(compiler, namer, rtiNeededClasses, emitter), | 95 new Collector(compiler, namer, rtiNeededClasses, emitter), |
| 94 this._registry = new Registry(compiler); | 96 this._registry = new Registry(compiler); |
| 95 | 97 |
| 96 JavaScriptBackend get backend => _compiler.backend; | 98 JavaScriptBackend get backend => _compiler.backend; |
| 99 BackendHelpers get helpers => backend.helpers; |
| 97 Universe get universe => _compiler.codegenWorld; | 100 Universe get universe => _compiler.codegenWorld; |
| 98 | 101 |
| 99 /// Mapping from [ClassElement] to constructed [Class]. We need this to | 102 /// Mapping from [ClassElement] to constructed [Class]. We need this to |
| 100 /// update the superclass in the [Class]. | 103 /// update the superclass in the [Class]. |
| 101 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; | 104 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; |
| 102 | 105 |
| 103 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to | 106 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to |
| 104 /// generate the deferredLoadingMap (to know which hunks to load). | 107 /// generate the deferredLoadingMap (to know which hunks to load). |
| 105 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; | 108 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; |
| 106 | 109 |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 js.js('function() { return this.#(this) }', toStringInvocation))); | 361 js.js('function() { return this.#(this) }', toStringInvocation))); |
| 359 } | 362 } |
| 360 | 363 |
| 361 // We add all members from classes marked with isJsInterop to the base | 364 // We add all members from classes marked with isJsInterop to the base |
| 362 // Interceptor class with implementations that directly call the | 365 // Interceptor class with implementations that directly call the |
| 363 // corresponding JavaScript member. We do not attempt to bind this when | 366 // corresponding JavaScript member. We do not attempt to bind this when |
| 364 // tearing off JavaScript methods as we cannot distinguish between calling | 367 // tearing off JavaScript methods as we cannot distinguish between calling |
| 365 // a regular getter that returns a JavaScript function and tearing off | 368 // a regular getter that returns a JavaScript function and tearing off |
| 366 // a method in the case where there exist multiple JavaScript classes | 369 // a method in the case where there exist multiple JavaScript classes |
| 367 // that conflict on whether the member is a getter or a method. | 370 // that conflict on whether the member is a getter or a method. |
| 368 var interceptorClass = _classes[backend.jsJavaScriptObjectClass]; | 371 var interceptorClass = _classes[helpers.jsJavaScriptObjectClass]; |
| 369 var stubNames = new Set<String>(); | 372 var stubNames = new Set<String>(); |
| 370 librariesMap.forEach((LibraryElement library, List<Element> elements) { | 373 librariesMap.forEach((LibraryElement library, List<Element> elements) { |
| 371 for (Element e in elements) { | 374 for (Element e in elements) { |
| 372 if (e is ClassElement && backend.isJsInterop(e)) { | 375 if (e is ClassElement && backend.isJsInterop(e)) { |
| 373 e.declaration.forEachMember((_, Element member) { | 376 e.declaration.forEachMember((_, Element member) { |
| 374 if (!member.isInstanceMember) return; | 377 if (!member.isInstanceMember) return; |
| 375 if (member.isGetter || member.isField || member.isFunction) { | 378 if (member.isGetter || member.isField || member.isFunction) { |
| 376 var selectors = | 379 var selectors = |
| 377 _compiler.codegenWorld.getterInvocationsByName(member.name); | 380 _compiler.codegenWorld.getterInvocationsByName(member.name); |
| 378 if (selectors != null && !selectors.isEmpty) { | 381 if (selectors != null && !selectors.isEmpty) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 // Note that a library-element may have multiple [Library]s, if it is split | 445 // Note that a library-element may have multiple [Library]s, if it is split |
| 443 // into multiple output units. | 446 // into multiple output units. |
| 444 Library _buildLibrary(LibraryElement library, List<Element> elements) { | 447 Library _buildLibrary(LibraryElement library, List<Element> elements) { |
| 445 String uri = library.canonicalUri.toString(); | 448 String uri = library.canonicalUri.toString(); |
| 446 | 449 |
| 447 List<StaticMethod> statics = elements | 450 List<StaticMethod> statics = elements |
| 448 .where((e) => e is FunctionElement) | 451 .where((e) => e is FunctionElement) |
| 449 .map(_buildStaticMethod) | 452 .map(_buildStaticMethod) |
| 450 .toList(); | 453 .toList(); |
| 451 | 454 |
| 452 if (library == backend.interceptorsLibrary) { | 455 if (library == helpers.interceptorsLibrary) { |
| 453 statics.addAll(_generateGetInterceptorMethods()); | 456 statics.addAll(_generateGetInterceptorMethods()); |
| 454 statics.addAll(_generateOneShotInterceptors()); | 457 statics.addAll(_generateOneShotInterceptors()); |
| 455 } | 458 } |
| 456 | 459 |
| 457 List<Class> classes = elements | 460 List<Class> classes = elements |
| 458 .where((e) => e is ClassElement) | 461 .where((e) => e is ClassElement) |
| 459 .map((ClassElement classElement) => _classes[classElement]) | 462 .map((ClassElement classElement) => _classes[classElement]) |
| 460 .where((Class cls) => | 463 .where((Class cls) => |
| 461 !cls.isNative || !_unneededNativeClasses.contains(cls)) | 464 !cls.isNative || !_unneededNativeClasses.contains(cls)) |
| 462 .toList(growable: false); | 465 .toList(growable: false); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 if (selector.isSetter) selectorName = "$selectorName="; | 540 if (selector.isSetter) selectorName = "$selectorName="; |
| 538 if (backend.symbolsUsed.contains(selectorName)) { | 541 if (backend.symbolsUsed.contains(selectorName)) { |
| 539 _symbolsMap[name] = selectorName; | 542 _symbolsMap[name] = selectorName; |
| 540 } | 543 } |
| 541 noSuchMethodStubs | 544 noSuchMethodStubs |
| 542 .add(classStubGenerator.generateStubForNoSuchMethod(name, | 545 .add(classStubGenerator.generateStubForNoSuchMethod(name, |
| 543 selector)); | 546 selector)); |
| 544 }); | 547 }); |
| 545 } | 548 } |
| 546 | 549 |
| 547 if (element == backend.closureClass) { | 550 if (element == helpers.closureClass) { |
| 548 // We add a special getter here to allow for tearing off a closure from | 551 // We add a special getter here to allow for tearing off a closure from |
| 549 // itself. | 552 // itself. |
| 550 js.Name name = namer.getterForMember(Names.call); | 553 js.Name name = namer.getterForMember(Names.call); |
| 551 js.Fun function = js.js('function() { return this; }'); | 554 js.Fun function = js.js('function() { return this; }'); |
| 552 callStubs.add(_buildStubMethod(name, function)); | 555 callStubs.add(_buildStubMethod(name, function)); |
| 553 } | 556 } |
| 554 | 557 |
| 555 ClassElement implementation = element.implementation; | 558 ClassElement implementation = element.implementation; |
| 556 | 559 |
| 557 // MixinApplications run through the members of their mixin. Here, we are | 560 // MixinApplications run through the members of their mixin. Here, we are |
| 558 // only interested in direct members. | 561 // only interested in direct members. |
| 559 if (!onlyForRti && !element.isMixinApplication) { | 562 if (!onlyForRti && !element.isMixinApplication) { |
| 560 implementation.forEachMember(visitMember, includeBackendMembers: true); | 563 implementation.forEachMember(visitMember, includeBackendMembers: true); |
| 561 } | 564 } |
| 562 | 565 |
| 563 List<Field> instanceFields = | 566 List<Field> instanceFields = |
| 564 onlyForRti ? const <Field>[] : _buildFields(element, false); | 567 onlyForRti ? const <Field>[] : _buildFields(element, false); |
| 565 List<Field> staticFieldsForReflection = | 568 List<Field> staticFieldsForReflection = |
| 566 onlyForRti ? const <Field>[] : _buildFields(element, true); | 569 onlyForRti ? const <Field>[] : _buildFields(element, true); |
| 567 | 570 |
| 568 TypeTestProperties typeTests = | 571 TypeTestProperties typeTests = |
| 569 runtimeTypeGenerator.generateIsTests( | 572 runtimeTypeGenerator.generateIsTests( |
| 570 element, | 573 element, |
| 571 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); | 574 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); |
| 572 | 575 |
| 573 List<StubMethod> checkedSetters = <StubMethod>[]; | 576 List<StubMethod> checkedSetters = <StubMethod>[]; |
| 574 List<StubMethod> isChecks = <StubMethod>[]; | 577 List<StubMethod> isChecks = <StubMethod>[]; |
| 575 if (backend.isJsInterop(element)) { | 578 if (backend.isJsInterop(element)) { |
| 576 typeTests.properties.forEach((js.Name name, js.Node code) { | 579 typeTests.properties.forEach((js.Name name, js.Node code) { |
| 577 _classes[backend.jsInterceptorClass].isChecks.add( | 580 _classes[helpers.jsInterceptorClass].isChecks.add( |
| 578 _buildStubMethod(name, code)); | 581 _buildStubMethod(name, code)); |
| 579 }); | 582 }); |
| 580 } else { | 583 } else { |
| 581 for (Field field in instanceFields) { | 584 for (Field field in instanceFields) { |
| 582 if (field.needsCheckedSetter) { | 585 if (field.needsCheckedSetter) { |
| 583 assert(!field.needsUncheckedSetter); | 586 assert(!field.needsUncheckedSetter); |
| 584 Element element = field.element; | 587 Element element = field.element; |
| 585 js.Expression code = backend.generatedCode[element]; | 588 js.Expression code = backend.generatedCode[element]; |
| 586 assert(code != null); | 589 assert(code != null); |
| 587 js.Name name = namer.deriveSetterName(field.accessorName); | 590 js.Name name = namer.deriveSetterName(field.accessorName); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 Class cls = _classes[element]; | 810 Class cls = _classes[element]; |
| 808 if (cls != null) cls.isEager = true; | 811 if (cls != null) cls.isEager = true; |
| 809 } | 812 } |
| 810 } | 813 } |
| 811 } | 814 } |
| 812 | 815 |
| 813 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { | 816 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { |
| 814 InterceptorStubGenerator stubGenerator = | 817 InterceptorStubGenerator stubGenerator = |
| 815 new InterceptorStubGenerator(_compiler, namer, backend); | 818 new InterceptorStubGenerator(_compiler, namer, backend); |
| 816 | 819 |
| 817 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); | 820 String holderName = namer.globalObjectFor(helpers.interceptorsLibrary); |
| 818 // TODO(floitsch): we shouldn't update the registry in the middle of | 821 // TODO(floitsch): we shouldn't update the registry in the middle of |
| 819 // generating the interceptor methods. | 822 // generating the interceptor methods. |
| 820 Holder holder = _registry.registerHolder(holderName); | 823 Holder holder = _registry.registerHolder(holderName); |
| 821 | 824 |
| 822 Map<js.Name, Set<ClassElement>> specializedGetInterceptors = | 825 Map<js.Name, Set<ClassElement>> specializedGetInterceptors = |
| 823 backend.specializedGetInterceptors; | 826 backend.specializedGetInterceptors; |
| 824 List<js.Name> names = specializedGetInterceptors.keys.toList()..sort(); | 827 List<js.Name> names = specializedGetInterceptors.keys.toList()..sort(); |
| 825 return names.map((js.Name name) { | 828 return names.map((js.Name name) { |
| 826 Set<ClassElement> classes = specializedGetInterceptors[name]; | 829 Set<ClassElement> classes = specializedGetInterceptors[name]; |
| 827 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); | 830 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 needsCheckedSetter)); | 875 needsCheckedSetter)); |
| 873 }); | 876 }); |
| 874 | 877 |
| 875 return fields; | 878 return fields; |
| 876 } | 879 } |
| 877 | 880 |
| 878 Iterable<StaticStubMethod> _generateOneShotInterceptors() { | 881 Iterable<StaticStubMethod> _generateOneShotInterceptors() { |
| 879 InterceptorStubGenerator stubGenerator = | 882 InterceptorStubGenerator stubGenerator = |
| 880 new InterceptorStubGenerator(_compiler, namer, backend); | 883 new InterceptorStubGenerator(_compiler, namer, backend); |
| 881 | 884 |
| 882 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); | 885 String holderName = namer.globalObjectFor(helpers.interceptorsLibrary); |
| 883 // TODO(floitsch): we shouldn't update the registry in the middle of | 886 // TODO(floitsch): we shouldn't update the registry in the middle of |
| 884 // generating the interceptor methods. | 887 // generating the interceptor methods. |
| 885 Holder holder = _registry.registerHolder(holderName); | 888 Holder holder = _registry.registerHolder(holderName); |
| 886 | 889 |
| 887 List<js.Name> names = backend.oneShotInterceptors.keys.toList()..sort(); | 890 List<js.Name> names = backend.oneShotInterceptors.keys.toList()..sort(); |
| 888 return names.map((js.Name name) { | 891 return names.map((js.Name name) { |
| 889 js.Expression code = stubGenerator.generateOneShotInterceptor(name); | 892 js.Expression code = stubGenerator.generateOneShotInterceptor(name); |
| 890 return new StaticStubMethod(name, holder, code); | 893 return new StaticStubMethod(name, holder, code); |
| 891 }); | 894 }); |
| 892 } | 895 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 Constant constant = new Constant(name, holder, constantValue); | 964 Constant constant = new Constant(name, holder, constantValue); |
| 962 _constants[constantValue] = constant; | 965 _constants[constantValue] = constant; |
| 963 } | 966 } |
| 964 } | 967 } |
| 965 | 968 |
| 966 Holder _registerStaticStateHolder() { | 969 Holder _registerStaticStateHolder() { |
| 967 return _registry.registerHolder( | 970 return _registry.registerHolder( |
| 968 namer.staticStateHolder, isStaticStateHolder: true); | 971 namer.staticStateHolder, isStaticStateHolder: true); |
| 969 } | 972 } |
| 970 } | 973 } |
| OLD | NEW |