| 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 |