OLD | NEW |
1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Fletch 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 library fletchc.fletch_backend; | 5 library fletchc.fletch_backend; |
6 | 6 |
7 import 'dart:async' show | 7 import 'dart:async' show |
8 Future; | 8 Future; |
9 | 9 |
10 import 'dart:collection' show | 10 import 'dart:collection' show |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 ConstructorElement, | 43 ConstructorElement, |
44 Element, | 44 Element, |
45 ExecutableElement, | 45 ExecutableElement, |
46 FieldElement, | 46 FieldElement, |
47 FormalElement, | 47 FormalElement, |
48 FunctionElement, | 48 FunctionElement, |
49 FunctionSignature, | 49 FunctionSignature, |
50 FunctionTypedElement, | 50 FunctionTypedElement, |
51 LibraryElement, | 51 LibraryElement, |
52 MemberElement, | 52 MemberElement, |
| 53 MethodElement, |
53 Name, | 54 Name, |
54 ParameterElement, | 55 ParameterElement, |
55 PublicName; | 56 PublicName; |
56 | 57 |
57 import 'package:compiler/src/universe/selector.dart' show | 58 import 'package:compiler/src/universe/selector.dart' show |
58 Selector; | 59 Selector; |
59 | 60 |
60 import 'package:compiler/src/universe/use.dart' show | 61 import 'package:compiler/src/universe/use.dart' show |
61 DynamicUse, | 62 DynamicUse, |
62 StaticUse, | 63 StaticUse, |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 // This class is optional. | 460 // This class is optional. |
460 coroutineClass = fletchSystemLibrary.implementation.find("Coroutine"); | 461 coroutineClass = fletchSystemLibrary.implementation.find("Coroutine"); |
461 if (coroutineClass != null) { | 462 if (coroutineClass != null) { |
462 coroutineClass.ensureResolved(compiler.resolution); | 463 coroutineClass.ensureResolved(compiler.resolution); |
463 } | 464 } |
464 } | 465 } |
465 | 466 |
466 void onElementResolved(Element element, TreeElements elements) { | 467 void onElementResolved(Element element, TreeElements elements) { |
467 if (alwaysEnqueue.contains(element)) { | 468 if (alwaysEnqueue.contains(element)) { |
468 var registry = new FletchRegistry(compiler); | 469 var registry = new FletchRegistry(compiler); |
469 if (element.isStatic || element.isTopLevel) { | 470 registry.registerStaticInvocation(element); |
470 registry.registerStaticUse(new StaticUse.foreignUse(element)); | |
471 } else { | |
472 registry.registerDynamicUse(new Selector.fromElement(element)); | |
473 } | |
474 } | 471 } |
475 } | 472 } |
476 | 473 |
477 ClassElement get intImplementation => smiClass; | 474 ClassElement get intImplementation => smiClass; |
478 | 475 |
479 /// Class of annotations to mark patches in patch files. | 476 /// Class of annotations to mark patches in patch files. |
480 /// | 477 /// |
481 /// The patch parser (pkg/compiler/lib/src/patch_parser.dart). The patch | 478 /// The patch parser (pkg/compiler/lib/src/patch_parser.dart). The patch |
482 /// parser looks for an annotation on the form "@patch", where "patch" is | 479 /// parser looks for an annotation on the form "@patch", where "patch" is |
483 /// compile-time constant instance of [patchAnnotationClass]. | 480 /// compile-time constant instance of [patchAnnotationClass]. |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 if (!isExactParameterMatch(function.signature, selector.callStructure)) { | 921 if (!isExactParameterMatch(function.signature, selector.callStructure)) { |
925 createParameterStubFor(function, selector); | 922 createParameterStubFor(function, selector); |
926 } | 923 } |
927 }); | 924 }); |
928 } | 925 } |
929 | 926 |
930 void codegenFunction( | 927 void codegenFunction( |
931 FunctionElement function, | 928 FunctionElement function, |
932 TreeElements elements, | 929 TreeElements elements, |
933 FletchRegistry registry) { | 930 FletchRegistry registry) { |
934 registry.registerStaticUse(new StaticUse.foreignUse(fletchSystemEntry)); | 931 registry.registerStaticInvocation(fletchSystemEntry); |
935 | 932 |
936 ClosureEnvironment closureEnvironment = createClosureEnvironment( | 933 ClosureEnvironment closureEnvironment = createClosureEnvironment( |
937 function, | 934 function, |
938 elements); | 935 elements); |
939 | 936 |
940 FletchFunctionBuilder functionBuilder; | 937 FletchFunctionBuilder functionBuilder; |
941 | 938 |
942 if (function.memberContext != function) { | 939 if (function.memberContext != function) { |
943 functionBuilder = internalCreateFletchFunctionBuilder( | 940 functionBuilder = internalCreateFletchFunctionBuilder( |
944 function, | 941 function, |
(...skipping 13 matching lines...) Expand all Loading... |
958 | 955 |
959 if (isNative(function)) { | 956 if (isNative(function)) { |
960 codegenNativeFunction(function, codegen); | 957 codegenNativeFunction(function, codegen); |
961 } else if (isExternal(function)) { | 958 } else if (isExternal(function)) { |
962 codegenExternalFunction(function, codegen); | 959 codegenExternalFunction(function, codegen); |
963 } else { | 960 } else { |
964 codegen.compile(); | 961 codegen.compile(); |
965 } | 962 } |
966 | 963 |
967 if (functionBuilder.isInstanceMember && !function.isGenerativeConstructor) { | 964 if (functionBuilder.isInstanceMember && !function.isGenerativeConstructor) { |
| 965 Name name = function is MethodElement |
| 966 ? function.memberName |
| 967 : new Name(functionBuilder.name, function.library); |
968 // Inject the function into the method table of the 'holderClass' class. | 968 // Inject the function into the method table of the 'holderClass' class. |
969 // Note that while constructor bodies has a this argument, we don't inject | 969 // Note that while constructor bodies has a this argument, we don't inject |
970 // them into the method table. | 970 // them into the method table. |
971 String symbol = context.getSymbolForFunction( | 971 String symbol = context.getSymbolForFunction(name, |
972 functionBuilder.name, | 972 function.functionSignature); |
973 function.functionSignature, | |
974 function.library); | |
975 int id = context.getSymbolId(symbol); | 973 int id = context.getSymbolId(symbol); |
976 int arity = function.functionSignature.parameterCount; | 974 int arity = function.functionSignature.parameterCount; |
977 SelectorKind kind = SelectorKind.Method; | 975 SelectorKind kind = SelectorKind.Method; |
978 if (function.isGetter) kind = SelectorKind.Getter; | 976 if (function.isGetter) kind = SelectorKind.Getter; |
979 if (function.isSetter) kind = SelectorKind.Setter; | 977 if (function.isSetter) kind = SelectorKind.Setter; |
980 int fletchSelector = FletchSelector.encode(id, kind, arity); | 978 int fletchSelector = FletchSelector.encode(id, kind, arity); |
981 FletchClassBuilder classBuilder = | 979 FletchClassBuilder classBuilder = |
982 systemBuilder.lookupClassBuilder(functionBuilder.memberOf); | 980 systemBuilder.lookupClassBuilder(functionBuilder.memberOf); |
983 classBuilder.addToMethodTable(fletchSelector, functionBuilder); | 981 classBuilder.addToMethodTable(fletchSelector, functionBuilder); |
984 // Inject method into all mixin usages. | 982 // Inject method into all mixin usages. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 // The static native method `Coroutine._coroutineNewStack` will invoke | 1023 // The static native method `Coroutine._coroutineNewStack` will invoke |
1026 // the instance method `Coroutine._coroutineStart`. | 1024 // the instance method `Coroutine._coroutineStart`. |
1027 if (coroutineClass == null) { | 1025 if (coroutineClass == null) { |
1028 compiler.reporter.internalError( | 1026 compiler.reporter.internalError( |
1029 function, "required class [Coroutine] not found"); | 1027 function, "required class [Coroutine] not found"); |
1030 } | 1028 } |
1031 FunctionElement coroutineStart = | 1029 FunctionElement coroutineStart = |
1032 coroutineClass.lookupLocalMember("_coroutineStart"); | 1030 coroutineClass.lookupLocalMember("_coroutineStart"); |
1033 Selector selector = new Selector.fromElement(coroutineStart); | 1031 Selector selector = new Selector.fromElement(coroutineStart); |
1034 new FletchRegistry(compiler) | 1032 new FletchRegistry(compiler) |
1035 ..registerDynamicUse(selector); | 1033 ..registerDynamicSelector(selector); |
1036 } else if (name == "Process._spawn") { | 1034 } else if (name == "Process._spawn") { |
1037 // The native method `Process._spawn` will do a closure invoke with 0, 1, | 1035 // The native method `Process._spawn` will do a closure invoke with 0, 1, |
1038 // or 2 arguments. | 1036 // or 2 arguments. |
1039 new FletchRegistry(compiler) | 1037 new FletchRegistry(compiler) |
1040 ..registerDynamicUse(new Selector.callClosure(0)) | 1038 ..registerDynamicSelector(new Selector.callClosure(0)) |
1041 ..registerDynamicUse(new Selector.callClosure(1)) | 1039 ..registerDynamicSelector(new Selector.callClosure(1)) |
1042 ..registerDynamicUse(new Selector.callClosure(2)); | 1040 ..registerDynamicSelector(new Selector.callClosure(2)); |
1043 } | 1041 } |
1044 | 1042 |
1045 int arity = codegen.assembler.functionArity; | 1043 int arity = codegen.assembler.functionArity; |
1046 if (name == "Port.send" || | 1044 if (name == "Port.send" || |
1047 name == "Port._sendList" || | 1045 name == "Port._sendList" || |
1048 name == "Port._sendExit") { | 1046 name == "Port._sendExit") { |
1049 codegen.assembler.invokeNativeYield(arity, descriptor.index); | 1047 codegen.assembler.invokeNativeYield(arity, descriptor.index); |
1050 } else { | 1048 } else { |
1051 codegen.assembler.invokeNative(arity, descriptor.index); | 1049 codegen.assembler.invokeNative(arity, descriptor.index); |
1052 } | 1050 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 }); | 1171 }); |
1174 } | 1172 } |
1175 | 1173 |
1176 void markFunctionConstantAsUsed(FunctionConstantValue value) { | 1174 void markFunctionConstantAsUsed(FunctionConstantValue value) { |
1177 // TODO(ajohnsen): Use registry in CodegenVisitor to register the used | 1175 // TODO(ajohnsen): Use registry in CodegenVisitor to register the used |
1178 // constants. | 1176 // constants. |
1179 FunctionElement function = value.element; | 1177 FunctionElement function = value.element; |
1180 createTearoffClass(createFletchFunctionBuilder(function)); | 1178 createTearoffClass(createFletchFunctionBuilder(function)); |
1181 // Be sure to actually enqueue the function for compilation. | 1179 // Be sure to actually enqueue the function for compilation. |
1182 FletchRegistry registry = new FletchRegistry(compiler); | 1180 FletchRegistry registry = new FletchRegistry(compiler); |
1183 registry.registerStaticUse(new StaticUse.foreignUse(function)); | 1181 registry.registerStaticInvocation(function); |
1184 } | 1182 } |
1185 | 1183 |
1186 FletchFunctionBase createParameterStubFor( | 1184 FletchFunctionBase createParameterStubFor( |
1187 FletchFunctionBase function, | 1185 FletchFunctionBase function, |
1188 Selector selector) { | 1186 Selector selector) { |
1189 CallStructure callStructure = selector.callStructure; | 1187 CallStructure callStructure = selector.callStructure; |
1190 assert(callStructure.signatureApplies(function.signature)); | 1188 assert(callStructure.signatureApplies(function.signature)); |
1191 FletchFunctionBase stub = systemBuilder.parameterStubFor( | 1189 FletchFunctionBase stub = systemBuilder.parameterStubFor( |
1192 function, | 1190 function, |
1193 callStructure); | 1191 callStructure); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 ..allocate(constId, tearoffClass.fields) | 1299 ..allocate(constId, tearoffClass.fields) |
1302 ..ret() | 1300 ..ret() |
1303 ..methodEnd(); | 1301 ..methodEnd(); |
1304 } | 1302 } |
1305 // If the name is private, we need the library. | 1303 // If the name is private, we need the library. |
1306 // Invariant: We only generate public stubs, e.g. 'call'. | 1304 // Invariant: We only generate public stubs, e.g. 'call'. |
1307 LibraryElement library; | 1305 LibraryElement library; |
1308 if (function.element != null) { | 1306 if (function.element != null) { |
1309 library = function.element.library; | 1307 library = function.element.library; |
1310 } | 1308 } |
1311 // TODO(sigurdm): Avoid allocating new name here. | 1309 // TODO(sigurdm): Avoid allocating new Name and Selector here. |
1312 Name name = new Name(function.name, library); | 1310 Name name = new Name(function.name, library); |
1313 int fletchSelector = context.toFletchSelector( | 1311 int fletchSelector = context.toFletchSelector( |
1314 new Selector.getter(name)); | 1312 new Selector.getter(name)); |
1315 FletchClassBuilder classBuilder = systemBuilder.lookupClassBuilder( | 1313 FletchClassBuilder classBuilder = systemBuilder.lookupClassBuilder( |
1316 function.memberOf); | 1314 function.memberOf); |
1317 classBuilder.addToMethodTable(fletchSelector, getter); | 1315 classBuilder.addToMethodTable(fletchSelector, getter); |
1318 | 1316 |
1319 // Inject getter into all mixin usages. | 1317 // Inject getter into all mixin usages. |
1320 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { | 1318 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { |
1321 FletchClassBuilder classBuilder = | 1319 FletchClassBuilder classBuilder = |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1673 return true; | 1671 return true; |
1674 } | 1672 } |
1675 | 1673 |
1676 static FletchBackend newInstance(FletchCompilerImplementation compiler) { | 1674 static FletchBackend newInstance(FletchCompilerImplementation compiler) { |
1677 return new FletchBackend(compiler); | 1675 return new FletchBackend(compiler); |
1678 } | 1676 } |
1679 | 1677 |
1680 Uri resolvePatchUri(String libraryName, Uri libraryRoot) { | 1678 Uri resolvePatchUri(String libraryName, Uri libraryRoot) { |
1681 throw "Not implemented"; | 1679 throw "Not implemented"; |
1682 } | 1680 } |
1683 | |
1684 } | 1681 } |
1685 | 1682 |
1686 class FletchImpactTransformer extends ImpactTransformer { | 1683 class FletchImpactTransformer extends ImpactTransformer { |
1687 final FletchBackend backend; | 1684 final FletchBackend backend; |
1688 | 1685 |
1689 FletchImpactTransformer(this.backend); | 1686 FletchImpactTransformer(this.backend); |
1690 | 1687 |
1691 @override | 1688 @override |
1692 WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) { | 1689 WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) { |
1693 TransformedWorldImpact transformed = | 1690 TransformedWorldImpact transformed = |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1729 return element.memberContext != element; | 1726 return element.memberContext != element; |
1730 } | 1727 } |
1731 return false; | 1728 return false; |
1732 } | 1729 } |
1733 | 1730 |
1734 Name memberName(AstElement element) { | 1731 Name memberName(AstElement element) { |
1735 if (isLocalFunction(element)) return null; | 1732 if (isLocalFunction(element)) return null; |
1736 MemberElement member = element; | 1733 MemberElement member = element; |
1737 return member.memberName; | 1734 return member.memberName; |
1738 } | 1735 } |
OLD | NEW |