| 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 |
| 11 Queue; | 11 Queue; |
| 12 | 12 |
| 13 import 'package:compiler/src/dart2jslib.dart' show | 13 import 'package:compiler/src/common/backend_api.dart' show |
| 14 Backend, | 14 Backend, |
| 15 BackendConstantEnvironment, | 15 ImpactTransformer; |
| 16 Compiler, | 16 |
| 17 CompilerTask, | 17 import 'package:compiler/src/common/tasks.dart' show |
| 18 ConstantCompilerTask, | 18 CompilerTask; |
| 19 |
| 20 import 'package:compiler/src/enqueue.dart' show |
| 19 Enqueuer, | 21 Enqueuer, |
| 20 MessageKind, | 22 ResolutionEnqueuer; |
| 21 Registry, | 23 |
| 22 ResolutionCallbacks, | 24 import 'package:compiler/src/diagnostics/messages.dart' show |
| 23 ResolutionEnqueuer, | 25 MessageKind; |
| 24 isPrivateName; | 26 |
| 27 import 'package:compiler/src/common/registry.dart' show |
| 28 Registry; |
| 25 | 29 |
| 26 import 'package:compiler/src/dart_types.dart' show | 30 import 'package:compiler/src/dart_types.dart' show |
| 27 DartType, | 31 DartType, |
| 28 InterfaceType; | 32 InterfaceType; |
| 29 | 33 |
| 30 import 'package:compiler/src/tree/tree.dart' show | 34 import 'package:compiler/src/tree/tree.dart' show |
| 31 DartString, | 35 DartString, |
| 32 EmptyStatement, | 36 EmptyStatement, |
| 33 Expression; | 37 Expression; |
| 34 | 38 |
| 35 import 'package:compiler/src/elements/elements.dart' show | 39 import 'package:compiler/src/elements/elements.dart' show |
| 36 AbstractFieldElement, | 40 AbstractFieldElement, |
| 37 AstElement, | 41 AstElement, |
| 38 ClassElement, | 42 ClassElement, |
| 39 ConstructorElement, | 43 ConstructorElement, |
| 40 Element, | 44 Element, |
| 41 ExecutableElement, | 45 ExecutableElement, |
| 42 FieldElement, | 46 FieldElement, |
| 43 FormalElement, | 47 FormalElement, |
| 44 FunctionElement, | 48 FunctionElement, |
| 45 FunctionSignature, | 49 FunctionSignature, |
| 46 FunctionTypedElement, | 50 FunctionTypedElement, |
| 47 LibraryElement, | 51 LibraryElement, |
| 48 MemberElement, | 52 MemberElement, |
| 49 Name, | 53 Name, |
| 50 ParameterElement; | 54 ParameterElement, |
| 55 PublicName; |
| 51 | 56 |
| 52 import 'package:compiler/src/universe/universe.dart' show | 57 import 'package:compiler/src/universe/selector.dart' show |
| 53 CallStructure, | 58 Selector; |
| 54 Selector, | |
| 55 UniverseSelector; | |
| 56 | 59 |
| 57 import 'package:compiler/src/util/util.dart' show | 60 import 'package:compiler/src/universe/use.dart' show |
| 61 DynamicUse, |
| 62 StaticUse, |
| 63 TypeUse, |
| 64 TypeUseKind; |
| 65 |
| 66 import 'package:compiler/src/universe/call_structure.dart' show |
| 67 CallStructure; |
| 68 |
| 69 import 'package:compiler/src/common.dart' show |
| 58 Spannable; | 70 Spannable; |
| 59 | 71 |
| 60 import 'package:compiler/src/elements/modelx.dart' show | 72 import 'package:compiler/src/elements/modelx.dart' show |
| 61 FunctionElementX; | 73 FunctionElementX; |
| 62 | 74 |
| 63 import 'package:compiler/src/dart_backend/dart_backend.dart' show | 75 import 'package:compiler/src/dart_backend/dart_backend.dart' show |
| 64 DartConstantTask; | 76 DartConstantTask; |
| 65 | 77 |
| 66 import 'package:compiler/src/constants/constant_system.dart' show | 78 import 'package:compiler/src/constants/constant_system.dart' show |
| 67 ConstantSystem; | 79 ConstantSystem; |
| 68 | 80 |
| 69 import 'package:compiler/src/compile_time_constants.dart' show | 81 import 'package:compiler/src/compile_time_constants.dart' show |
| 70 BackendConstantEnvironment; | 82 BackendConstantEnvironment; |
| 71 | 83 |
| 72 import 'package:compiler/src/constants/values.dart' show | 84 import 'package:compiler/src/constants/values.dart' show |
| 73 ConstantValue, | 85 ConstantValue, |
| 74 ConstructedConstantValue, | 86 ConstructedConstantValue, |
| 75 FunctionConstantValue, | 87 FunctionConstantValue, |
| 76 ListConstantValue, | 88 ListConstantValue, |
| 77 MapConstantValue, | 89 MapConstantValue, |
| 78 StringConstantValue; | 90 StringConstantValue; |
| 79 | 91 |
| 80 import 'package:compiler/src/constants/expressions.dart' show | 92 import 'package:compiler/src/constants/expressions.dart' show |
| 81 ConstantExpression; | 93 ConstantExpression; |
| 82 | 94 |
| 83 import 'package:compiler/src/resolution/resolution.dart' show | 95 import 'package:compiler/src/resolution/tree_elements.dart' show |
| 84 TreeElements; | 96 TreeElements; |
| 85 | 97 |
| 86 import 'package:compiler/src/library_loader.dart' show | 98 import 'package:compiler/src/library_loader.dart' show |
| 87 LibraryLoader; | 99 LibraryLoader; |
| 88 | 100 |
| 89 import 'package:persistent/persistent.dart' show | 101 import 'package:persistent/persistent.dart' show |
| 90 PersistentMap; | 102 PersistentMap; |
| 91 | 103 |
| 92 import 'fletch_function_builder.dart' show | 104 import 'fletch_function_builder.dart' show |
| 93 FletchFunctionKind, | 105 FletchFunctionBuilder; |
| 94 FletchFunctionBuilder, | |
| 95 DebugInfo; | |
| 96 | 106 |
| 97 import 'fletch_class_builder.dart' show | 107 import 'fletch_class_builder.dart' show |
| 98 FletchClassBuilder; | 108 FletchClassBuilder; |
| 99 | 109 |
| 100 import 'fletch_system_builder.dart' show | 110 import 'fletch_system_builder.dart' show |
| 101 FletchSystemBuilder; | 111 FletchSystemBuilder; |
| 102 | 112 |
| 103 import '../incremental_backend.dart' show | 113 import '../incremental_backend.dart' show |
| 104 IncrementalFletchBackend; | 114 IncrementalFletchBackend; |
| 105 | 115 |
| 106 import 'fletch_enqueuer.dart' show | 116 import 'fletch_enqueuer.dart' show |
| 107 FletchEnqueueTask, | 117 FletchEnqueueTask, |
| 108 shouldReportEnqueuingOfElement; | 118 shouldReportEnqueuingOfElement; |
| 109 | 119 |
| 110 import 'fletch_registry.dart' show | 120 import 'fletch_registry.dart' show |
| 111 ClosureKind, | 121 ClosureKind, |
| 112 FletchRegistry; | 122 FletchRegistry; |
| 113 | 123 |
| 114 import 'diagnostic.dart' show | 124 import 'diagnostic.dart' show |
| 115 throwInternalError; | 125 throwInternalError; |
| 116 | 126 |
| 127 import 'package:compiler/src/common/names.dart' show |
| 128 Identifiers, |
| 129 Names; |
| 130 |
| 131 import 'package:compiler/src/universe/world_impact.dart' show |
| 132 TransformedWorldImpact, |
| 133 WorldImpact, |
| 134 WorldImpactBuilder; |
| 135 |
| 117 import 'class_debug_info.dart'; | 136 import 'class_debug_info.dart'; |
| 118 import 'codegen_visitor.dart'; | 137 import 'codegen_visitor.dart'; |
| 119 import 'debug_info.dart'; | 138 import 'debug_info.dart'; |
| 120 import 'debug_info_constructor_codegen.dart'; | 139 import 'debug_info_constructor_codegen.dart'; |
| 121 import 'debug_info_function_codegen.dart'; | 140 import 'debug_info_function_codegen.dart'; |
| 122 import 'debug_info_lazy_field_initializer_codegen.dart'; | 141 import 'debug_info_lazy_field_initializer_codegen.dart'; |
| 123 import 'fletch_context.dart'; | 142 import 'fletch_context.dart'; |
| 124 import 'fletch_selector.dart'; | 143 import 'fletch_selector.dart'; |
| 125 import 'function_codegen.dart'; | 144 import 'function_codegen.dart'; |
| 126 import 'lazy_field_initializer_codegen.dart'; | 145 import 'lazy_field_initializer_codegen.dart'; |
| 127 import 'constructor_codegen.dart'; | 146 import 'constructor_codegen.dart'; |
| 128 import 'closure_environment.dart'; | 147 import 'closure_environment.dart'; |
| 129 | 148 |
| 130 import '../bytecodes.dart'; | 149 import '../bytecodes.dart'; |
| 131 import '../commands.dart'; | 150 import '../commands.dart'; |
| 132 import '../fletch_system.dart'; | 151 import '../fletch_system.dart'; |
| 152 import 'package:compiler/src/common/resolution.dart'; |
| 133 | 153 |
| 134 const FletchSystem BASE_FLETCH_SYSTEM = const FletchSystem( | 154 const FletchSystem BASE_FLETCH_SYSTEM = const FletchSystem( |
| 135 const PersistentMap<int, FletchFunction>(), | 155 const PersistentMap<int, FletchFunction>(), |
| 136 const PersistentMap<Element, FletchFunction>(), | 156 const PersistentMap<Element, FletchFunction>(), |
| 137 const PersistentMap<ConstructorElement, FletchFunction>(), | 157 const PersistentMap<ConstructorElement, FletchFunction>(), |
| 138 const PersistentMap<int, int>(), | 158 const PersistentMap<int, int>(), |
| 139 const PersistentMap<int, FletchClass>(), | 159 const PersistentMap<int, FletchClass>(), |
| 140 const PersistentMap<ClassElement, FletchClass>(), | 160 const PersistentMap<ClassElement, FletchClass>(), |
| 141 const <FletchConstant>[], | 161 const <FletchConstant>[], |
| 142 const PersistentMap<int, String>(), | 162 const PersistentMap<int, String>(), |
| 143 const PersistentMap<int, int>(), | 163 const PersistentMap<int, int>(), |
| 144 const PersistentMap<int, int>()); | 164 const PersistentMap<int, int>()); |
| 145 | 165 |
| 146 class FletchBackend extends Backend with ResolutionCallbacks | 166 class FletchBackend extends Backend |
| 147 implements IncrementalFletchBackend { | 167 implements IncrementalFletchBackend { |
| 148 static const String growableListName = '_GrowableList'; | 168 static const String growableListName = '_GrowableList'; |
| 149 static const String constantListName = '_ConstantList'; | 169 static const String constantListName = '_ConstantList'; |
| 150 static const String constantByteListName = '_ConstantByteList'; | 170 static const String constantByteListName = '_ConstantByteList'; |
| 151 static const String constantMapName = '_ConstantMap'; | 171 static const String constantMapName = '_ConstantMap'; |
| 152 static const String fletchNoSuchMethodErrorName = 'FletchNoSuchMethodError'; | 172 static const String fletchNoSuchMethodErrorName = 'FletchNoSuchMethodError'; |
| 153 static const String noSuchMethodName = '_noSuchMethod'; | 173 static const String noSuchMethodName = '_noSuchMethod'; |
| 154 static const String noSuchMethodTrampolineName = '_noSuchMethodTrampoline'; | 174 static const String noSuchMethodTrampolineName = '_noSuchMethodTrampoline'; |
| 155 | 175 |
| 156 final FletchContext context; | 176 final FletchContext context; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 ClassElement bigintClass; | 237 ClassElement bigintClass; |
| 218 ClassElement uint32DigitsClass; | 238 ClassElement uint32DigitsClass; |
| 219 | 239 |
| 220 /// Holds a reference to the class Coroutine if it exists. | 240 /// Holds a reference to the class Coroutine if it exists. |
| 221 ClassElement coroutineClass; | 241 ClassElement coroutineClass; |
| 222 | 242 |
| 223 FletchSystemBuilder systemBuilder; | 243 FletchSystemBuilder systemBuilder; |
| 224 | 244 |
| 225 final Set<FunctionElement> alwaysEnqueue = new Set<FunctionElement>(); | 245 final Set<FunctionElement> alwaysEnqueue = new Set<FunctionElement>(); |
| 226 | 246 |
| 247 FletchImpactTransformer impactTransformer; |
| 248 |
| 227 FletchBackend(FletchCompilerImplementation compiler) | 249 FletchBackend(FletchCompilerImplementation compiler) |
| 228 : this.context = compiler.context, | 250 : this.context = compiler.context, |
| 229 this.constantCompilerTask = new DartConstantTask(compiler), | 251 this.constantCompilerTask = new DartConstantTask(compiler), |
| 230 this.systemBuilder = new FletchSystemBuilder(BASE_FLETCH_SYSTEM), | 252 this.systemBuilder = new FletchSystemBuilder(BASE_FLETCH_SYSTEM), |
| 231 super(compiler); | 253 super(compiler) { |
| 254 this.impactTransformer = new FletchImpactTransformer(this); |
| 255 } |
| 232 | 256 |
| 233 void newSystemBuilder(FletchSystem predecessorSystem) { | 257 void newSystemBuilder(FletchSystem predecessorSystem) { |
| 234 systemBuilder = new FletchSystemBuilder(predecessorSystem); | 258 systemBuilder = new FletchSystemBuilder(predecessorSystem); |
| 235 } | 259 } |
| 236 | 260 |
| 237 FletchClassBuilder registerClassElement(ClassElement element) { | 261 FletchClassBuilder registerClassElement(ClassElement element) { |
| 238 if (element == null) return null; | 262 if (element == null) return null; |
| 239 assert(element.isDeclaration); | 263 assert(element.isDeclaration); |
| 240 | 264 |
| 241 FletchClassBuilder classBuilder = | 265 FletchClassBuilder classBuilder = |
| 242 systemBuilder.lookupClassBuilderByElement(element); | 266 systemBuilder.lookupClassBuilderByElement(element); |
| 243 if (classBuilder != null) return classBuilder; | 267 if (classBuilder != null) return classBuilder; |
| 244 | 268 |
| 245 directSubclasses[element] = new Set<ClassElement>(); | 269 directSubclasses[element] = new Set<ClassElement>(); |
| 246 FletchClassBuilder superclass = registerClassElement(element.superclass); | 270 FletchClassBuilder superclass = registerClassElement(element.superclass); |
| 247 if (superclass != null) { | 271 if (superclass != null) { |
| 248 Set<ClassElement> subclasses = directSubclasses[element.superclass]; | 272 Set<ClassElement> subclasses = directSubclasses[element.superclass]; |
| 249 subclasses.add(element); | 273 subclasses.add(element); |
| 250 } | 274 } |
| 251 classBuilder = systemBuilder.newClassBuilder( | 275 classBuilder = systemBuilder.newClassBuilder( |
| 252 element, superclass, builtinClasses.contains(element)); | 276 element, superclass, builtinClasses.contains(element)); |
| 253 | 277 |
| 254 // TODO(ajohnsen): Currently, the FletchRegistry does not enqueue fields. | 278 // TODO(ajohnsen): Currently, the FletchRegistry does not enqueue fields. |
| 255 // This is a workaround, where we basically add getters for all fields. | 279 // This is a workaround, where we basically add getters for all fields. |
| 256 classBuilder.updateImplicitAccessors(this); | 280 classBuilder.updateImplicitAccessors(this); |
| 257 | 281 |
| 258 Element callMember = element.lookupLocalMember( | 282 Element callMember = element.lookupLocalMember(Identifiers.call); |
| 259 Compiler.CALL_OPERATOR_NAME); | |
| 260 if (callMember != null && callMember.isFunction) { | 283 if (callMember != null && callMember.isFunction) { |
| 261 FunctionElement function = callMember; | 284 FunctionElement function = callMember; |
| 262 classBuilder.createIsFunctionEntry( | 285 classBuilder.createIsFunctionEntry( |
| 263 this, function.functionSignature.parameterCount); | 286 this, function.functionSignature.parameterCount); |
| 264 } | 287 } |
| 265 return classBuilder; | 288 return classBuilder; |
| 266 } | 289 } |
| 267 | 290 |
| 268 FletchClassBuilder createCallableStubClass( | 291 FletchClassBuilder createCallableStubClass( |
| 269 int fields, int arity, FletchClassBuilder superclass) { | 292 int fields, int arity, FletchClassBuilder superclass) { |
| 270 FletchClassBuilder classBuilder = systemBuilder.newClassBuilder( | 293 FletchClassBuilder classBuilder = systemBuilder.newClassBuilder( |
| 271 null, superclass, false, extraFields: fields); | 294 null, superclass, false, extraFields: fields); |
| 272 classBuilder.createIsFunctionEntry(this, arity); | 295 classBuilder.createIsFunctionEntry(this, arity); |
| 273 return classBuilder; | 296 return classBuilder; |
| 274 } | 297 } |
| 275 | 298 |
| 276 ResolutionCallbacks get resolutionCallbacks => this; | |
| 277 | |
| 278 List<CompilerTask> get tasks => <CompilerTask>[]; | 299 List<CompilerTask> get tasks => <CompilerTask>[]; |
| 279 | 300 |
| 280 ConstantSystem get constantSystem { | 301 ConstantSystem get constantSystem { |
| 281 return constantCompilerTask.constantCompiler.constantSystem; | 302 return constantCompilerTask.constantCompiler.constantSystem; |
| 282 } | 303 } |
| 283 | 304 |
| 284 BackendConstantEnvironment get constants => constantCompilerTask; | 305 BackendConstantEnvironment get constants => constantCompilerTask; |
| 285 | 306 |
| 286 bool classNeedsRti(ClassElement cls) => false; | 307 bool classNeedsRti(ClassElement cls) => false; |
| 287 | 308 |
| 288 bool methodNeedsRti(FunctionElement function) => false; | 309 bool methodNeedsRti(FunctionElement function) => false; |
| 289 | 310 |
| 290 void enqueueHelpers(ResolutionEnqueuer world, incomingRegistry) { | 311 void enqueueHelpers(ResolutionEnqueuer world, Registry incomingRegistry) { |
| 291 FletchRegistry registry = incomingRegistry; | 312 FletchRegistry registry = new FletchRegistry(compiler); |
| 292 compiler.patchAnnotationClass = patchAnnotationClass; | 313 compiler.patchAnnotationClass = patchAnnotationClass; |
| 293 | 314 |
| 294 bool hasMissingHelpers = false; | 315 bool hasMissingHelpers = false; |
| 295 loadHelperMethods((String name) { | 316 loadHelperMethods((String name) { |
| 296 LibraryElement library = fletchSystemLibrary; | 317 LibraryElement library = fletchSystemLibrary; |
| 297 Element helper = library.findLocal(name); | 318 Element helper = library.findLocal(name); |
| 298 // TODO(ahe): Make it cleaner. | 319 // TODO(ahe): Make it cleaner. |
| 299 if (helper != null && helper.isAbstractField) { | 320 if (helper != null && helper.isAbstractField) { |
| 300 AbstractFieldElement abstractField = helper; | 321 AbstractFieldElement abstractField = helper; |
| 301 helper = abstractField.getter; | 322 helper = abstractField.getter; |
| 302 } | 323 } |
| 303 if (helper == null) { | 324 if (helper == null) { |
| 304 hasMissingHelpers = true; | 325 hasMissingHelpers = true; |
| 305 compiler.reportError( | 326 compiler.reporter.reportErrorMessage( |
| 306 library, MessageKind.GENERIC, | 327 library, MessageKind.GENERIC, |
| 307 {'text': "Required implementation method '$name' not found."}); | 328 {'text': "Required implementation method '$name' not found."}); |
| 308 } | 329 } |
| 309 return helper; | 330 return helper; |
| 310 }); | 331 }); |
| 311 if (hasMissingHelpers) { | 332 if (hasMissingHelpers) { |
| 312 throwInternalError( | 333 throwInternalError( |
| 313 "Some implementation methods are missing, see details above"); | 334 "Some implementation methods are missing, see details above"); |
| 314 } | 335 } |
| 315 world.registerStaticUse(fletchCompileError); | 336 world.registerStaticUse( |
| 316 world.registerStaticUse(fletchSystemEntry); | 337 new StaticUse.staticInvoke(fletchCompileError, CallStructure.NO_ARGS)); |
| 317 world.registerStaticUse(fletchUnresolved); | 338 world.registerStaticUse( |
| 339 new StaticUse.staticInvoke(fletchSystemEntry, CallStructure.ONE_ARG)); |
| 340 world.registerStaticUse( |
| 341 new StaticUse.staticInvoke(fletchUnresolved, CallStructure.ONE_ARG)); |
| 318 | 342 |
| 319 loadHelperClasses(( | 343 loadHelperClasses(( |
| 320 String name, | 344 String name, |
| 321 LibraryElement library, | 345 LibraryElement library, |
| 322 {bool builtin: false}) { | 346 {bool builtin: false}) { |
| 323 var classImpl = library.findLocal(name); | 347 var classImpl = library.findLocal(name); |
| 324 if (classImpl == null) classImpl = library.implementation.find(name); | 348 if (classImpl == null) classImpl = library.implementation.find(name); |
| 325 if (classImpl == null) { | 349 if (classImpl == null) { |
| 326 compiler.reportError( | 350 compiler.reporter.reportErrorMessage( |
| 327 library, MessageKind.GENERIC, | 351 library, MessageKind.GENERIC, |
| 328 {'text': "Required implementation class '$name' not found."}); | 352 {'text': "Required implementation class '$name' not found."}); |
| 329 hasMissingHelpers = true; | 353 hasMissingHelpers = true; |
| 330 return null; | 354 return null; |
| 331 } | 355 } |
| 332 if (hasMissingHelpers) return null; | 356 if (hasMissingHelpers) return null; |
| 333 if (builtin) builtinClasses.add(classImpl); | 357 if (builtin) builtinClasses.add(classImpl); |
| 334 { | 358 { |
| 335 // TODO(ahe): Register in ResolutionCallbacks. The lines in this block | 359 // TODO(ahe): Register in ResolutionCallbacks. The lines in this block |
| 336 // should not happen at this point in time. | 360 // should not happen at this point in time. |
| 337 classImpl.ensureResolved(compiler); | 361 classImpl.ensureResolved(compiler.resolution); |
| 338 world.registerInstantiatedType(classImpl.rawType, registry.asRegistry); | 362 world.registerInstantiatedType(classImpl.rawType); |
| 339 // TODO(ahe): This is a hack to let both the world and the codegen know | 363 // TODO(ahe): This is a hack to let both the world and the codegen know |
| 340 // about the instantiated type. | 364 // about the instantiated type. |
| 341 registry.registerInstantiatedType(classImpl.rawType); | 365 registry.registerInstantiatedType(classImpl.rawType); |
| 342 } | 366 } |
| 343 return registerClassElement(classImpl); | 367 return registerClassElement(classImpl); |
| 344 }); | 368 }); |
| 345 if (hasMissingHelpers) { | 369 if (hasMissingHelpers) { |
| 346 throwInternalError( | 370 throwInternalError( |
| 347 "Some implementation classes are missing, see details above"); | 371 "Some implementation classes are missing, see details above"); |
| 348 } | 372 } |
| 349 | 373 |
| 350 // Register list constructors to world. | 374 // Register list constructors to world. |
| 351 // TODO(ahe): Register growableListClass through ResolutionCallbacks. | 375 // TODO(ahe): Register growableListClass through ResolutionCallbacks. |
| 352 growableListClass.constructors.forEach(world.registerStaticUse); | 376 growableListClass.constructors.forEach((Element element) { |
| 377 world.registerStaticUse(new StaticUse.constructorInvoke(element, null)); |
| 378 }); |
| 353 | 379 |
| 354 // TODO(ajohnsen): Remove? String interpolation does not enqueue '+'. | 380 // TODO(ajohnsen): Remove? String interpolation does not enqueue '+'. |
| 355 // Investigate what else it may enqueue, could be StringBuilder, and then | 381 // Investigate what else it may enqueue, could be StringBuilder, and then |
| 356 // consider using that instead. | 382 // consider using that instead. |
| 357 var selector = new UniverseSelector(new Selector.binaryOperator('+'), null); | 383 world.registerDynamicUse( |
| 358 world.registerDynamicInvocation(selector); | 384 new DynamicUse(new Selector.binaryOperator('+'), null)); |
| 359 | 385 |
| 360 selector = new UniverseSelector(new Selector.call('add', null, 1), null); | 386 world.registerDynamicUse(new DynamicUse( |
| 361 world.registerDynamicInvocation(selector); | 387 new Selector.call(new PublicName('add'), CallStructure.ONE_ARG), null)); |
| 362 | 388 |
| 363 alwaysEnqueue.add(compiler.objectClass.implementation.lookupLocalMember( | 389 alwaysEnqueue.add( |
| 364 noSuchMethodTrampolineName)); | 390 compiler.coreClasses.objectClass.implementation.lookupLocalMember( |
| 365 alwaysEnqueue.add(compiler.objectClass.implementation.lookupLocalMember( | 391 noSuchMethodTrampolineName)); |
| 366 noSuchMethodName)); | 392 alwaysEnqueue.add( |
| 393 compiler.coreClasses.objectClass.implementation.lookupLocalMember( |
| 394 noSuchMethodName)); |
| 367 | 395 |
| 368 if (coroutineClass != null) { | 396 if (coroutineClass != null) { |
| 369 builtinClasses.add(coroutineClass); | 397 builtinClasses.add(coroutineClass); |
| 370 alwaysEnqueue.add(coroutineClass.lookupLocalMember("_coroutineStart")); | 398 alwaysEnqueue.add(coroutineClass.lookupLocalMember("_coroutineStart")); |
| 371 } | 399 } |
| 372 | 400 |
| 373 for (FunctionElement element in alwaysEnqueue) { | 401 for (FunctionElement element in alwaysEnqueue) { |
| 374 world.registerStaticUse(element); | 402 world.registerStaticUse(new StaticUse.foreignUse(element)); |
| 375 } | 403 } |
| 376 } | 404 } |
| 377 | 405 |
| 378 void loadHelperMethods( | 406 void loadHelperMethods( |
| 379 FunctionElement findHelper(String name)) { | 407 FunctionElement findHelper(String name)) { |
| 380 | 408 |
| 381 FunctionElement findExternal(String name) { | 409 FunctionElement findExternal(String name) { |
| 382 FunctionElement helper = findHelper(name); | 410 FunctionElement helper = findHelper(name); |
| 383 if (helper != null) externals.add(helper); | 411 if (helper != null) externals.add(helper); |
| 384 return helper; | 412 return helper; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 growableListClass = | 452 growableListClass = |
| 425 loadClass(growableListName, fletchSystemLibrary)?.element; | 453 loadClass(growableListName, fletchSystemLibrary)?.element; |
| 426 fletchNoSuchMethodErrorClass = | 454 fletchNoSuchMethodErrorClass = |
| 427 loadClass(fletchNoSuchMethodErrorName, | 455 loadClass(fletchNoSuchMethodErrorName, |
| 428 fletchSystemLibrary, | 456 fletchSystemLibrary, |
| 429 builtin: true)?.element; | 457 builtin: true)?.element; |
| 430 | 458 |
| 431 // This class is optional. | 459 // This class is optional. |
| 432 coroutineClass = fletchSystemLibrary.implementation.find("Coroutine"); | 460 coroutineClass = fletchSystemLibrary.implementation.find("Coroutine"); |
| 433 if (coroutineClass != null) { | 461 if (coroutineClass != null) { |
| 434 coroutineClass.ensureResolved(compiler); | 462 coroutineClass.ensureResolved(compiler.resolution); |
| 435 } | 463 } |
| 436 } | 464 } |
| 437 | 465 |
| 438 void onElementResolved(Element element, TreeElements elements) { | 466 void onElementResolved(Element element, TreeElements elements) { |
| 439 if (alwaysEnqueue.contains(element)) { | 467 if (alwaysEnqueue.contains(element)) { |
| 440 var registry = new FletchRegistry(compiler, elements); | 468 var registry = new FletchRegistry(compiler); |
| 441 registry.registerStaticInvocation(element); | 469 if (element.isStatic || element.isTopLevel) { |
| 470 registry.registerStaticUse(new StaticUse.foreignUse(element)); |
| 471 } else { |
| 472 registry.registerDynamicUse(new Selector.fromElement(element)); |
| 473 } |
| 442 } | 474 } |
| 443 } | 475 } |
| 444 | 476 |
| 445 void onMapLiteral(Registry registry, DartType type, bool isConstant) { | |
| 446 if (isConstant) return; | |
| 447 ClassElement classImpl = mapImplementation; | |
| 448 registry.registerInstantiation(classImpl.rawType); | |
| 449 registry.registerStaticInvocation(classImpl.lookupDefaultConstructor()); | |
| 450 } | |
| 451 | |
| 452 ClassElement get intImplementation => smiClass; | 477 ClassElement get intImplementation => smiClass; |
| 453 | 478 |
| 454 /// Class of annotations to mark patches in patch files. | 479 /// Class of annotations to mark patches in patch files. |
| 455 /// | 480 /// |
| 456 /// The patch parser (pkg/compiler/lib/src/patch_parser.dart). The patch | 481 /// The patch parser (pkg/compiler/lib/src/patch_parser.dart). The patch |
| 457 /// parser looks for an annotation on the form "@patch", where "patch" is | 482 /// parser looks for an annotation on the form "@patch", where "patch" is |
| 458 /// compile-time constant instance of [patchAnnotationClass]. | 483 /// compile-time constant instance of [patchAnnotationClass]. |
| 459 ClassElement get patchAnnotationClass { | 484 ClassElement get patchAnnotationClass { |
| 460 // TODO(ahe): Introduce a proper constant class to identify constants. For | 485 // TODO(ahe): Introduce a proper constant class to identify constants. For |
| 461 // now, we simply put "const patch = "patch";" in the beginning of patch | 486 // now, we simply put "const patch = "patch";" in fletch._system. |
| 462 // files. | |
| 463 return super.stringImplementation; | 487 return super.stringImplementation; |
| 464 } | 488 } |
| 465 | 489 |
| 466 FletchClassBuilder createClosureClass( | 490 FletchClassBuilder createClosureClass( |
| 467 FunctionElement closure, | 491 FunctionElement closure, |
| 468 ClosureEnvironment closureEnvironment) { | 492 ClosureEnvironment closureEnvironment) { |
| 469 return closureClasses.putIfAbsent(closure, () { | 493 return closureClasses.putIfAbsent(closure, () { |
| 470 ClosureInfo info = closureEnvironment.closures[closure]; | 494 ClosureInfo info = closureEnvironment.closures[closure]; |
| 471 int fields = info.free.length; | 495 int fields = info.free.length; |
| 472 if (info.isThisFree) fields++; | 496 if (info.isThisFree) fields++; |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 elements); | 713 elements); |
| 690 CodegenVisitor codegen; | 714 CodegenVisitor codegen; |
| 691 FletchFunctionBuilder builder = | 715 FletchFunctionBuilder builder = |
| 692 new FletchFunctionBuilder.fromFletchFunction(function); | 716 new FletchFunctionBuilder.fromFletchFunction(function); |
| 693 if (function.isLazyFieldInitializer) { | 717 if (function.isLazyFieldInitializer) { |
| 694 codegen = new DebugInfoLazyFieldInitializerCodegen( | 718 codegen = new DebugInfoLazyFieldInitializerCodegen( |
| 695 debugInfo, | 719 debugInfo, |
| 696 builder, | 720 builder, |
| 697 context, | 721 context, |
| 698 elements, | 722 elements, |
| 699 null, | |
| 700 closureEnvironment, | 723 closureEnvironment, |
| 701 element, | 724 element, |
| 702 compiler); | 725 compiler); |
| 703 } else if (function.isInitializerList) { | 726 } else if (function.isInitializerList) { |
| 704 ClassElement enclosingClass = element.enclosingClass; | 727 ClassElement enclosingClass = element.enclosingClass; |
| 705 // TODO(ajohnsen): Don't depend on the class builder. | 728 // TODO(ajohnsen): Don't depend on the class builder. |
| 706 FletchClassBuilder classBuilder = | 729 FletchClassBuilder classBuilder = |
| 707 systemBuilder.lookupClassBuilderByElement(enclosingClass.declaration); | 730 systemBuilder.lookupClassBuilderByElement(enclosingClass.declaration); |
| 708 codegen = new DebugInfoConstructorCodegen( | 731 codegen = new DebugInfoConstructorCodegen( |
| 709 debugInfo, | 732 debugInfo, |
| 710 builder, | 733 builder, |
| 711 context, | 734 context, |
| 712 elements, | 735 elements, |
| 713 null, | |
| 714 closureEnvironment, | 736 closureEnvironment, |
| 715 element, | 737 element, |
| 716 classBuilder, | 738 classBuilder, |
| 717 compiler); | 739 compiler); |
| 718 } else { | 740 } else { |
| 719 codegen = new DebugInfoFunctionCodegen( | 741 codegen = new DebugInfoFunctionCodegen( |
| 720 debugInfo, | 742 debugInfo, |
| 721 builder, | 743 builder, |
| 722 context, | 744 context, |
| 723 elements, | 745 elements, |
| 724 null, | |
| 725 closureEnvironment, | 746 closureEnvironment, |
| 726 element, | 747 element, |
| 727 compiler); | 748 compiler); |
| 728 } | 749 } |
| 729 if (isNative(element)) { | 750 if (isNative(element)) { |
| 730 compiler.withCurrentElement(element, () { | 751 compiler.reporter.withCurrentElement(element, () { |
| 731 codegenNativeFunction(element, codegen); | 752 codegenNativeFunction(element, codegen); |
| 732 }); | 753 }); |
| 733 } else if (isExternal(element)) { | 754 } else if (isExternal(element)) { |
| 734 compiler.withCurrentElement(element, () { | 755 compiler.reporter.withCurrentElement(element, () { |
| 735 codegenExternalFunction(element, codegen); | 756 codegenExternalFunction(element, codegen); |
| 736 }); | 757 }); |
| 737 } else { | 758 } else { |
| 738 compiler.withCurrentElement(element, () { codegen.compile(); }); | 759 compiler.reporter.withCurrentElement(element, () { codegen.compile(); }); |
| 739 } | 760 } |
| 740 // The debug codegen should generate the same bytecodes as the original | 761 // The debug codegen should generate the same bytecodes as the original |
| 741 // codegen. If that is not the case debug information will be useless. | 762 // codegen. If that is not the case debug information will be useless. |
| 742 assert(Bytecode.identicalBytecodes(expectedBytecodes, | 763 assert(Bytecode.identicalBytecodes(expectedBytecodes, |
| 743 codegen.assembler.bytecodes)); | 764 codegen.assembler.bytecodes)); |
| 744 return debugInfo; | 765 return debugInfo; |
| 745 } | 766 } |
| 746 | 767 |
| 747 codegen(_) { | 768 codegen(_) { |
| 748 new UnsupportedError( | 769 new UnsupportedError( |
| 749 "Method [codegen] not supported, use [compileElement] instead"); | 770 "Method [codegen] not supported, use [compileElement] instead"); |
| 750 } | 771 } |
| 751 | 772 |
| 752 /// Invoked by [FletchEnqueuer] once per element that needs to be compiled. | 773 /// Invoked by [FletchEnqueuer] once per element that needs to be compiled. |
| 753 /// | 774 /// |
| 754 /// This is used to generate the bytecodes for [declaration]. | 775 /// This is used to generate the bytecodes for [declaration]. |
| 755 void compileElement( | 776 void compileElement( |
| 756 AstElement declaration, | 777 AstElement declaration, |
| 757 TreeElements treeElements, | 778 TreeElements treeElements, |
| 758 FletchRegistry registry) { | 779 FletchRegistry registry) { |
| 759 AstElement element = declaration.implementation; | 780 AstElement element = declaration.implementation; |
| 760 compiler.withCurrentElement(element, () { | 781 compiler.reporter.withCurrentElement(element, () { |
| 761 assert(declaration.isDeclaration); | 782 assert(declaration.isDeclaration); |
| 762 context.compiler.reportVerboseInfo(element, 'Compiling $element'); | 783 context.compiler.reportVerboseInfo(element, 'Compiling $element'); |
| 763 if (element.isFunction || | 784 if (element.isFunction || |
| 764 element.isGetter || | 785 element.isGetter || |
| 765 element.isSetter || | 786 element.isSetter || |
| 766 element.isGenerativeConstructor) { | 787 element.isGenerativeConstructor || |
| 788 element.isFactoryConstructor) { |
| 767 // For a generative constructor, this means compile the constructor | 789 // For a generative constructor, this means compile the constructor |
| 768 // body. See [compilePendingConstructorInitializers] for an overview of | 790 // body. See [compilePendingConstructorInitializers] for an overview of |
| 769 // how constructor initializers and constructor bodies are compiled. | 791 // how constructor initializers and constructor bodies are compiled. |
| 770 codegenFunction(element, treeElements, registry); | 792 codegenFunction(element, treeElements, registry); |
| 771 } else if (element.isField) { | 793 } else if (element.isField) { |
| 772 context.compiler.reportVerboseInfo( | 794 context.compiler.reportVerboseInfo( |
| 773 element, "Asked to compile a field, but don't know how"); | 795 element, "Asked to compile a field, but don't know how"); |
| 774 } else { | 796 } else { |
| 775 compiler.internalError( | 797 compiler.reporter.internalError( |
| 776 element, "Uninimplemented element kind: ${element.kind}"); | 798 element, "Uninimplemented element kind: ${element.kind}"); |
| 777 } | 799 } |
| 778 }); | 800 }); |
| 779 } | 801 } |
| 780 | 802 |
| 781 /// Invoked by [FletchEnqueuer] once per [selector] that may invoke | 803 /// Invoked by [FletchEnqueuer] once per [selector] that may invoke |
| 782 /// [declaration]. | 804 /// [declaration]. |
| 783 /// | 805 /// |
| 784 /// This is used to generate stubs for [declaration]. | 806 /// This is used to generate stubs for [declaration]. |
| 785 void compileElementUsage( | 807 void compileElementUsage( |
| 786 AstElement declaration, | 808 AstElement declaration, |
| 787 Selector selector, | 809 Selector selector, |
| 788 TreeElements treeElements, | 810 TreeElements treeElements, |
| 789 FletchRegistry registry) { | 811 FletchRegistry registry) { |
| 790 AstElement element = declaration.implementation; | 812 AstElement element = declaration.implementation; |
| 791 compiler.withCurrentElement(element, () { | 813 compiler.reporter.withCurrentElement(element, () { |
| 792 assert(declaration.isDeclaration); | 814 assert(declaration.isDeclaration); |
| 793 context.compiler.reportVerboseInfo(element, 'Compiling $element'); | 815 context.compiler.reportVerboseInfo(element, 'Compiling $element'); |
| 794 if (!element.isInstanceMember && !isLocalFunction(element)) { | 816 if (!element.isInstanceMember && !isLocalFunction(element)) { |
| 795 // No stub needed. Optional arguments are handled at call-site. | 817 // No stub needed. Optional arguments are handled at call-site. |
| 796 } else if (element.isFunction) { | 818 } else if (element.isFunction) { |
| 797 FletchFunctionBase function = | 819 FletchFunctionBase function = |
| 798 systemBuilder.lookupFunctionBuilderByElement(element.declaration); | 820 systemBuilder.lookupFunctionBuilderByElement(element.declaration); |
| 799 CallStructure callStructure = selector.callStructure; | 821 CallStructure callStructure = selector.callStructure; |
| 800 FunctionSignature signature = function.signature; | 822 FunctionSignature signature = function.signature; |
| 801 if (selector.isGetter) { | 823 if (selector.isGetter) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 828 /// [declaration] as an implicit closure (for example, a tear-off). | 850 /// [declaration] as an implicit closure (for example, a tear-off). |
| 829 /// | 851 /// |
| 830 /// This is used to generate parameter stubs for the closures. | 852 /// This is used to generate parameter stubs for the closures. |
| 831 void compileClosurizationUsage( | 853 void compileClosurizationUsage( |
| 832 AstElement declaration, | 854 AstElement declaration, |
| 833 Selector selector, | 855 Selector selector, |
| 834 TreeElements treeElements, | 856 TreeElements treeElements, |
| 835 FletchRegistry registry, | 857 FletchRegistry registry, |
| 836 ClosureKind kind) { | 858 ClosureKind kind) { |
| 837 AstElement element = declaration.implementation; | 859 AstElement element = declaration.implementation; |
| 838 compiler.withCurrentElement(element, () { | 860 compiler.reporter.withCurrentElement(element, () { |
| 839 assert(declaration.isDeclaration); | 861 assert(declaration.isDeclaration); |
| 840 if (shouldReportEnqueuingOfElement(compiler, element)) { | 862 if (shouldReportEnqueuingOfElement(compiler, element)) { |
| 841 context.compiler.reportVerboseInfo( | 863 context.compiler.reportVerboseInfo( |
| 842 element, 'Need tear-off parameter stub $selector'); | 864 element, 'Need tear-off parameter stub $selector'); |
| 843 } | 865 } |
| 844 FletchFunctionBase function = | 866 FletchFunctionBase function = |
| 845 systemBuilder.lookupFunctionByElement(element.declaration); | 867 systemBuilder.lookupFunctionByElement(element.declaration); |
| 846 if (function == null) { | 868 if (function == null) { |
| 847 compiler.internalError( | 869 compiler.reporter.internalError( |
| 848 element, "Has no fletch function, but used as tear-off"); | 870 element, "Has no fletch function, but used as tear-off"); |
| 849 } | 871 } |
| 850 if (selector.isGetter) { | 872 if (selector.isGetter) { |
| 851 // This is a special tear-off getter. | 873 // This is a special tear-off getter. |
| 852 | 874 |
| 853 // TODO(ahe): This code should probably use [kind] to detect the | 875 // TODO(ahe): This code should probably use [kind] to detect the |
| 854 // various cases instead of [isLocalFunction] and looking at names. | 876 // various cases instead of [isLocalFunction] and looking at names. |
| 855 | 877 |
| 856 assert(selector.memberName == Selector.CALL_NAME); | 878 assert(selector.memberName == Names.CALL_NAME); |
| 857 if (isLocalFunction(element) || | 879 if (isLocalFunction(element) || |
| 858 memberName(element) == Selector.CALL_NAME) { | 880 memberName(element) == Names.CALL_NAME) { |
| 859 createTearoffGetterForFunction( | 881 createTearoffGetterForFunction( |
| 860 function, isSpecialCallMethod: true); | 882 function, isSpecialCallMethod: true); |
| 861 return; | 883 return; |
| 862 } | 884 } |
| 863 int stub = systemBuilder.lookupTearOffById(function.functionId); | 885 int stub = systemBuilder.lookupTearOffById(function.functionId); |
| 864 if (stub == null) { | 886 if (stub == null) { |
| 865 compiler.internalError( | 887 compiler.reporter.internalError( |
| 866 element, "No tear-off stub to compile `call` tear-off"); | 888 element, "No tear-off stub to compile `call` tear-off"); |
| 867 } else { | 889 } else { |
| 868 function = systemBuilder.lookupFunction(stub); | 890 function = systemBuilder.lookupFunction(stub); |
| 869 createTearoffGetterForFunction(function, isSpecialCallMethod: true); | 891 createTearoffGetterForFunction(function, isSpecialCallMethod: true); |
| 870 return; | 892 return; |
| 871 } | 893 } |
| 872 } | 894 } |
| 873 switch (kind) { | 895 switch (kind) { |
| 874 case ClosureKind.tearOff: | 896 case ClosureKind.tearOff: |
| 875 case ClosureKind.superTearOff: | 897 case ClosureKind.superTearOff: |
| 876 if (memberName(element) == Selector.CALL_NAME) { | 898 if (memberName(element) == Names.CALL_NAME) { |
| 877 // This is really a functionLikeTearOff. | 899 // This is really a functionLikeTearOff. |
| 878 break; | 900 break; |
| 879 } | 901 } |
| 880 // A tear-off has a corresponding stub in a closure class. Look up | 902 // A tear-off has a corresponding stub in a closure class. Look up |
| 881 // that stub: | 903 // that stub: |
| 882 int stub = systemBuilder.lookupTearOffById(function.functionId); | 904 int stub = systemBuilder.lookupTearOffById(function.functionId); |
| 883 if (stub == null) { | 905 if (stub == null) { |
| 884 compiler.internalError(element, "Couldn't find tear-off stub"); | 906 compiler.reporter |
| 907 .internalError(element, "Couldn't find tear-off stub"); |
| 885 } else { | 908 } else { |
| 886 function = systemBuilder.lookupFunction(stub); | 909 function = systemBuilder.lookupFunction(stub); |
| 887 } | 910 } |
| 888 break; | 911 break; |
| 889 | 912 |
| 890 case ClosureKind.localFunction: | 913 case ClosureKind.localFunction: |
| 891 // A local function already is a member of its closure class, and | 914 // A local function already is a member of its closure class, and |
| 892 // doesn't have a stub. | 915 // doesn't have a stub. |
| 893 break; | 916 break; |
| 894 | 917 |
| 895 case ClosureKind.functionLike: | 918 case ClosureKind.functionLike: |
| 896 case ClosureKind.functionLikeTearOff: | 919 case ClosureKind.functionLikeTearOff: |
| 897 compiler.internalError(element, "Unimplemented: $kind"); | 920 compiler.reporter.internalError(element, "Unimplemented: $kind"); |
| 898 break; | 921 break; |
| 899 } | 922 } |
| 900 | 923 |
| 901 if (!isExactParameterMatch(function.signature, selector.callStructure)) { | 924 if (!isExactParameterMatch(function.signature, selector.callStructure)) { |
| 902 createParameterStubFor(function, selector); | 925 createParameterStubFor(function, selector); |
| 903 } | 926 } |
| 904 }); | 927 }); |
| 905 } | 928 } |
| 906 | 929 |
| 907 void codegenFunction( | 930 void codegenFunction( |
| 908 FunctionElement function, | 931 FunctionElement function, |
| 909 TreeElements elements, | 932 TreeElements elements, |
| 910 FletchRegistry registry) { | 933 FletchRegistry registry) { |
| 911 registry.registerStaticInvocation(fletchSystemEntry); | 934 registry.registerStaticUse(new StaticUse.foreignUse(fletchSystemEntry)); |
| 912 | 935 |
| 913 ClosureEnvironment closureEnvironment = createClosureEnvironment( | 936 ClosureEnvironment closureEnvironment = createClosureEnvironment( |
| 914 function, | 937 function, |
| 915 elements); | 938 elements); |
| 916 | 939 |
| 917 FletchFunctionBuilder functionBuilder; | 940 FletchFunctionBuilder functionBuilder; |
| 918 | 941 |
| 919 if (function.memberContext != function) { | 942 if (function.memberContext != function) { |
| 920 functionBuilder = internalCreateFletchFunctionBuilder( | 943 functionBuilder = internalCreateFletchFunctionBuilder( |
| 921 function, | 944 function, |
| 922 Compiler.CALL_OPERATOR_NAME, | 945 Identifiers.call, |
| 923 createClosureClass(function, closureEnvironment)); | 946 createClosureClass(function, closureEnvironment)); |
| 924 } else { | 947 } else { |
| 925 functionBuilder = createFletchFunctionBuilder(function); | 948 functionBuilder = createFletchFunctionBuilder(function); |
| 926 } | 949 } |
| 927 | 950 |
| 928 FunctionCodegen codegen = new FunctionCodegen( | 951 FunctionCodegen codegen = new FunctionCodegen( |
| 929 functionBuilder, | 952 functionBuilder, |
| 930 context, | 953 context, |
| 931 elements, | 954 elements, |
| 932 registry, | 955 registry, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 995 | 1018 |
| 996 FletchNativeDescriptor descriptor = context.nativeDescriptors[name]; | 1019 FletchNativeDescriptor descriptor = context.nativeDescriptors[name]; |
| 997 if (descriptor == null) { | 1020 if (descriptor == null) { |
| 998 throw "Unsupported native function: $name"; | 1021 throw "Unsupported native function: $name"; |
| 999 } | 1022 } |
| 1000 | 1023 |
| 1001 if (name == "Coroutine._coroutineNewStack") { | 1024 if (name == "Coroutine._coroutineNewStack") { |
| 1002 // The static native method `Coroutine._coroutineNewStack` will invoke | 1025 // The static native method `Coroutine._coroutineNewStack` will invoke |
| 1003 // the instance method `Coroutine._coroutineStart`. | 1026 // the instance method `Coroutine._coroutineStart`. |
| 1004 if (coroutineClass == null) { | 1027 if (coroutineClass == null) { |
| 1005 compiler.internalError( | 1028 compiler.reporter.internalError( |
| 1006 function, "required class [Coroutine] not found"); | 1029 function, "required class [Coroutine] not found"); |
| 1007 } | 1030 } |
| 1008 FunctionElement coroutineStart = | 1031 FunctionElement coroutineStart = |
| 1009 coroutineClass.lookupLocalMember("_coroutineStart"); | 1032 coroutineClass.lookupLocalMember("_coroutineStart"); |
| 1010 Selector selector = new Selector.fromElement(coroutineStart); | 1033 Selector selector = new Selector.fromElement(coroutineStart); |
| 1011 new FletchRegistry(compiler, function.resolvedAst.elements) | 1034 new FletchRegistry(compiler) |
| 1012 ..registerDynamicInvocation(new UniverseSelector(selector, null)); | 1035 ..registerDynamicUse(selector); |
| 1013 } else if (name == "Process._spawn") { | 1036 } else if (name == "Process._spawn") { |
| 1014 // The native method `Process._spawn` will do a closure invoke with 0, 1, | 1037 // The native method `Process._spawn` will do a closure invoke with 0, 1, |
| 1015 // or 2 arguments. | 1038 // or 2 arguments. |
| 1016 new FletchRegistry(compiler, function.resolvedAst.elements) | 1039 new FletchRegistry(compiler) |
| 1017 ..registerDynamicInvocation( | 1040 ..registerDynamicUse(new Selector.callClosure(0)) |
| 1018 new UniverseSelector(new Selector.callClosure(0), null)) | 1041 ..registerDynamicUse(new Selector.callClosure(1)) |
| 1019 ..registerDynamicInvocation( | 1042 ..registerDynamicUse(new Selector.callClosure(2)); |
| 1020 new UniverseSelector(new Selector.callClosure(1), null)) | |
| 1021 ..registerDynamicInvocation( | |
| 1022 new UniverseSelector(new Selector.callClosure(2), null)); | |
| 1023 } | 1043 } |
| 1024 | 1044 |
| 1025 int arity = codegen.assembler.functionArity; | 1045 int arity = codegen.assembler.functionArity; |
| 1026 if (name == "Port.send" || | 1046 if (name == "Port.send" || |
| 1027 name == "Port._sendList" || | 1047 name == "Port._sendList" || |
| 1028 name == "Port._sendExit") { | 1048 name == "Port._sendExit") { |
| 1029 codegen.assembler.invokeNativeYield(arity, descriptor.index); | 1049 codegen.assembler.invokeNativeYield(arity, descriptor.index); |
| 1030 } else { | 1050 } else { |
| 1031 codegen.assembler.invokeNative(arity, descriptor.index); | 1051 codegen.assembler.invokeNative(arity, descriptor.index); |
| 1032 } | 1052 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1048 if (function == fletchExternalYield) { | 1068 if (function == fletchExternalYield) { |
| 1049 codegenExternalYield(function, codegen); | 1069 codegenExternalYield(function, codegen); |
| 1050 } else if (function == context.compiler.identicalFunction.implementation) { | 1070 } else if (function == context.compiler.identicalFunction.implementation) { |
| 1051 codegenIdentical(function, codegen); | 1071 codegenIdentical(function, codegen); |
| 1052 } else if (function == fletchExternalInvokeMain) { | 1072 } else if (function == fletchExternalInvokeMain) { |
| 1053 codegenExternalInvokeMain(function, codegen); | 1073 codegenExternalInvokeMain(function, codegen); |
| 1054 } else if (function.name == noSuchMethodTrampolineName && | 1074 } else if (function.name == noSuchMethodTrampolineName && |
| 1055 function.library == compiler.coreLibrary) { | 1075 function.library == compiler.coreLibrary) { |
| 1056 codegenExternalNoSuchMethodTrampoline(function, codegen); | 1076 codegenExternalNoSuchMethodTrampoline(function, codegen); |
| 1057 } else { | 1077 } else { |
| 1058 compiler.reportError( | 1078 compiler.reporter.reportErrorMessage( |
| 1059 function.node, | 1079 function.node, |
| 1060 MessageKind.GENERIC, | 1080 MessageKind.GENERIC, |
| 1061 {'text': 'External function is not supported'}); | 1081 {'text': 'External function is not supported'}); |
| 1062 codegen | 1082 codegen |
| 1063 ..doCompileError() | 1083 ..doCompileError() |
| 1064 ..assembler.ret() | 1084 ..assembler.ret() |
| 1065 ..assembler.methodEnd(); | 1085 ..assembler.methodEnd(); |
| 1066 } | 1086 } |
| 1067 } | 1087 } |
| 1068 | 1088 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1083 codegen.assembler | 1103 codegen.assembler |
| 1084 ..loadParameter(0) | 1104 ..loadParameter(0) |
| 1085 ..processYield() | 1105 ..processYield() |
| 1086 ..ret() | 1106 ..ret() |
| 1087 ..methodEnd(); | 1107 ..methodEnd(); |
| 1088 } | 1108 } |
| 1089 | 1109 |
| 1090 void codegenExternalInvokeMain( | 1110 void codegenExternalInvokeMain( |
| 1091 FunctionElement function, | 1111 FunctionElement function, |
| 1092 FunctionCodegen codegen) { | 1112 FunctionCodegen codegen) { |
| 1093 compiler.internalError( | 1113 compiler.reporter.internalError( |
| 1094 function, "[codegenExternalInvokeMain] not implemented."); | 1114 function, "[codegenExternalInvokeMain] not implemented."); |
| 1095 // TODO(ahe): This code shouldn't normally be called, only if invokeMain is | 1115 // TODO(ahe): This code shouldn't normally be called, only if invokeMain is |
| 1096 // torn off. Perhaps we should just say we don't support that. | 1116 // torn off. Perhaps we should just say we don't support that. |
| 1097 } | 1117 } |
| 1098 | 1118 |
| 1099 void codegenExternalNoSuchMethodTrampoline( | 1119 void codegenExternalNoSuchMethodTrampoline( |
| 1100 FunctionElement function, | 1120 FunctionElement function, |
| 1101 FunctionCodegen codegen) { | 1121 FunctionCodegen codegen) { |
| 1102 // NOTE: The number of arguments to the [noSuchMethodName] function must be | 1122 // NOTE: The number of arguments to the [noSuchMethodName] function must be |
| 1103 // kept in sync with: | 1123 // kept in sync with: |
| 1104 // src/vm/interpreter.cc:HandleEnterNoSuchMethod | 1124 // src/vm/interpreter.cc:HandleEnterNoSuchMethod |
| 1105 int id = context.getSymbolId( | 1125 int id = context.getSymbolId( |
| 1106 context.mangleName(noSuchMethodName, compiler.coreLibrary)); | 1126 context.mangleName(new Name(noSuchMethodName, compiler.coreLibrary))); |
| 1107 int fletchSelector = FletchSelector.encodeMethod(id, 3); | 1127 int fletchSelector = FletchSelector.encodeMethod(id, 3); |
| 1108 BytecodeLabel skipGetter = new BytecodeLabel(); | 1128 BytecodeLabel skipGetter = new BytecodeLabel(); |
| 1109 codegen.assembler | 1129 codegen.assembler |
| 1110 ..enterNoSuchMethod(skipGetter) | 1130 ..enterNoSuchMethod(skipGetter) |
| 1111 // First invoke the getter. | 1131 // First invoke the getter. |
| 1112 ..invokeSelector() | 1132 ..invokeSelector() |
| 1113 // Then invoke 'call', with the receiver being the result of the | 1133 // Then invoke 'call', with the receiver being the result of the |
| 1114 // previous invokeSelector. | 1134 // previous invokeSelector. |
| 1115 ..invokeSelector() | 1135 ..invokeSelector() |
| 1116 ..exitNoSuchMethod() | 1136 ..exitNoSuchMethod() |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 return environment.compute(); | 1172 return environment.compute(); |
| 1153 }); | 1173 }); |
| 1154 } | 1174 } |
| 1155 | 1175 |
| 1156 void markFunctionConstantAsUsed(FunctionConstantValue value) { | 1176 void markFunctionConstantAsUsed(FunctionConstantValue value) { |
| 1157 // TODO(ajohnsen): Use registry in CodegenVisitor to register the used | 1177 // TODO(ajohnsen): Use registry in CodegenVisitor to register the used |
| 1158 // constants. | 1178 // constants. |
| 1159 FunctionElement function = value.element; | 1179 FunctionElement function = value.element; |
| 1160 createTearoffClass(createFletchFunctionBuilder(function)); | 1180 createTearoffClass(createFletchFunctionBuilder(function)); |
| 1161 // Be sure to actually enqueue the function for compilation. | 1181 // Be sure to actually enqueue the function for compilation. |
| 1162 FletchRegistry registry = | 1182 FletchRegistry registry = new FletchRegistry(compiler); |
| 1163 new FletchRegistry(compiler, function.resolvedAst.elements); | 1183 registry.registerStaticUse(new StaticUse.foreignUse(function)); |
| 1164 registry.registerStaticInvocation(function); | |
| 1165 } | 1184 } |
| 1166 | 1185 |
| 1167 FletchFunctionBase createParameterStubFor( | 1186 FletchFunctionBase createParameterStubFor( |
| 1168 FletchFunctionBase function, | 1187 FletchFunctionBase function, |
| 1169 Selector selector) { | 1188 Selector selector) { |
| 1170 CallStructure callStructure = selector.callStructure; | 1189 CallStructure callStructure = selector.callStructure; |
| 1171 assert(callStructure.signatureApplies(function.signature)); | 1190 assert(callStructure.signatureApplies(function.signature)); |
| 1172 FletchFunctionBase stub = systemBuilder.parameterStubFor( | 1191 FletchFunctionBase stub = systemBuilder.parameterStubFor( |
| 1173 function, | 1192 function, |
| 1174 callStructure); | 1193 callStructure); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 ..allocate(constId, tearoffClass.fields) | 1301 ..allocate(constId, tearoffClass.fields) |
| 1283 ..ret() | 1302 ..ret() |
| 1284 ..methodEnd(); | 1303 ..methodEnd(); |
| 1285 } | 1304 } |
| 1286 // If the name is private, we need the library. | 1305 // If the name is private, we need the library. |
| 1287 // Invariant: We only generate public stubs, e.g. 'call'. | 1306 // Invariant: We only generate public stubs, e.g. 'call'. |
| 1288 LibraryElement library; | 1307 LibraryElement library; |
| 1289 if (function.element != null) { | 1308 if (function.element != null) { |
| 1290 library = function.element.library; | 1309 library = function.element.library; |
| 1291 } | 1310 } |
| 1311 // TODO(sigurdm): Avoid allocating new name here. |
| 1312 Name name = new Name(function.name, library); |
| 1292 int fletchSelector = context.toFletchSelector( | 1313 int fletchSelector = context.toFletchSelector( |
| 1293 new Selector.getter(function.name, library)); | 1314 new Selector.getter(name)); |
| 1294 FletchClassBuilder classBuilder = systemBuilder.lookupClassBuilder( | 1315 FletchClassBuilder classBuilder = systemBuilder.lookupClassBuilder( |
| 1295 function.memberOf); | 1316 function.memberOf); |
| 1296 classBuilder.addToMethodTable(fletchSelector, getter); | 1317 classBuilder.addToMethodTable(fletchSelector, getter); |
| 1297 | 1318 |
| 1298 // Inject getter into all mixin usages. | 1319 // Inject getter into all mixin usages. |
| 1299 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { | 1320 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { |
| 1300 FletchClassBuilder classBuilder = | 1321 FletchClassBuilder classBuilder = |
| 1301 systemBuilder.lookupClassBuilderByElement(usage); | 1322 systemBuilder.lookupClassBuilderByElement(usage); |
| 1302 classBuilder.addToMethodTable(fletchSelector, getter); | 1323 classBuilder.addToMethodTable(fletchSelector, getter); |
| 1303 }); | 1324 }); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 | 1357 |
| 1337 bool enableCodegenWithErrorsIfSupported(Spannable spannable) { | 1358 bool enableCodegenWithErrorsIfSupported(Spannable spannable) { |
| 1338 return true; | 1359 return true; |
| 1339 } | 1360 } |
| 1340 | 1361 |
| 1341 bool enableDeferredLoadingIfSupported(Spannable spannable, Registry registry)
{ | 1362 bool enableDeferredLoadingIfSupported(Spannable spannable, Registry registry)
{ |
| 1342 return false; | 1363 return false; |
| 1343 } | 1364 } |
| 1344 | 1365 |
| 1345 bool registerDeferredLoading(Spannable node, Registry registry) { | 1366 bool registerDeferredLoading(Spannable node, Registry registry) { |
| 1346 compiler.reportWarning( | 1367 compiler.reporter.reportWarningMessage( |
| 1347 node, | 1368 node, |
| 1348 MessageKind.GENERIC, | 1369 MessageKind.GENERIC, |
| 1349 {'text': "Deferred loading is not supported."}); | 1370 {'text': "Deferred loading is not supported."}); |
| 1350 return false; | 1371 return false; |
| 1351 } | 1372 } |
| 1352 | 1373 |
| 1353 bool get supportsReflection => false; | 1374 bool get supportsReflection => false; |
| 1354 | 1375 |
| 1355 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { | 1376 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
| 1356 if (Uri.parse('dart:fletch._system') == library.canonicalUri) { | 1377 if (Uri.parse('dart:fletch._system') == library.canonicalUri) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1384 | 1405 |
| 1385 /// Return non-null to enable patching. Possible return values are 'new' and | 1406 /// Return non-null to enable patching. Possible return values are 'new' and |
| 1386 /// 'old'. Referring to old and new emitter. Since the new emitter is the | 1407 /// 'old'. Referring to old and new emitter. Since the new emitter is the |
| 1387 /// future, we assume 'old' will go away. So it seems the best option for | 1408 /// future, we assume 'old' will go away. So it seems the best option for |
| 1388 /// Fletch is 'new'. | 1409 /// Fletch is 'new'. |
| 1389 String get patchVersion => 'new'; | 1410 String get patchVersion => 'new'; |
| 1390 | 1411 |
| 1391 FunctionElement resolveExternalFunction(FunctionElement element) { | 1412 FunctionElement resolveExternalFunction(FunctionElement element) { |
| 1392 if (element.isPatched) { | 1413 if (element.isPatched) { |
| 1393 FunctionElementX patch = element.patch; | 1414 FunctionElementX patch = element.patch; |
| 1394 compiler.withCurrentElement(patch, () { | 1415 compiler.reporter.withCurrentElement(patch, () { |
| 1395 patch.parseNode(compiler); | 1416 patch.parseNode(compiler.parsing); |
| 1396 patch.computeType(compiler); | 1417 patch.computeType(compiler.resolution); |
| 1397 }); | 1418 }); |
| 1398 element = patch; | 1419 element = patch; |
| 1399 // TODO(ahe): Don't use ensureResolved (fix TODO in isNative instead). | 1420 // TODO(ahe): Don't use ensureResolved (fix TODO in isNative instead). |
| 1400 element.metadata.forEach((m) => m.ensureResolved(compiler)); | 1421 element.metadata.forEach((m) => m.ensureResolved(compiler.resolution)); |
| 1401 } else if (element.library == fletchSystemLibrary) { | 1422 } else if (element.library == fletchSystemLibrary) { |
| 1402 // Nothing needed for now. | 1423 // Nothing needed for now. |
| 1403 } else if (element.library == compiler.coreLibrary) { | 1424 } else if (element.library == compiler.coreLibrary) { |
| 1404 // Nothing needed for now. | 1425 // Nothing needed for now. |
| 1405 } else if (element.library == mathLibrary) { | 1426 } else if (element.library == mathLibrary) { |
| 1406 // Nothing needed for now. | 1427 // Nothing needed for now. |
| 1407 } else if (element.library == asyncLibrary) { | 1428 } else if (element.library == asyncLibrary) { |
| 1408 // Nothing needed for now. | 1429 // Nothing needed for now. |
| 1409 } else if (element.library == fletchLibrary) { | 1430 } else if (element.library == fletchLibrary) { |
| 1410 // Nothing needed for now. | 1431 // Nothing needed for now. |
| 1411 } else if (externals.contains(element)) { | 1432 } else if (externals.contains(element)) { |
| 1412 // Nothing needed for now. | 1433 // Nothing needed for now. |
| 1413 } else { | 1434 } else { |
| 1414 compiler.reportError( | 1435 compiler.reporter.reportErrorMessage( |
| 1415 element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); | 1436 element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); |
| 1416 } | 1437 } |
| 1417 return element; | 1438 return element; |
| 1418 } | 1439 } |
| 1419 | 1440 |
| 1420 int compileLazyFieldInitializer( | 1441 int compileLazyFieldInitializer( |
| 1421 FieldElement field, | 1442 FieldElement field, |
| 1422 FletchRegistry registry) { | 1443 FletchRegistry registry) { |
| 1423 int index = context.getStaticFieldIndex(field, null); | 1444 int index = context.getStaticFieldIndex(field, null); |
| 1424 | 1445 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1452 return index; | 1473 return index; |
| 1453 } | 1474 } |
| 1454 | 1475 |
| 1455 /// Compiles the initializer part of a constructor. | 1476 /// Compiles the initializer part of a constructor. |
| 1456 /// | 1477 /// |
| 1457 /// See [compilePendingConstructorInitializers] for an overview of how | 1478 /// See [compilePendingConstructorInitializers] for an overview of how |
| 1458 /// constructor initializer and bodies are compiled. | 1479 /// constructor initializer and bodies are compiled. |
| 1459 void compileConstructorInitializer(FletchFunctionBuilder functionBuilder) { | 1480 void compileConstructorInitializer(FletchFunctionBuilder functionBuilder) { |
| 1460 ConstructorElement constructor = functionBuilder.element; | 1481 ConstructorElement constructor = functionBuilder.element; |
| 1461 assert(constructor.isImplementation); | 1482 assert(constructor.isImplementation); |
| 1462 compiler.withCurrentElement(constructor, () { | 1483 compiler.reporter.withCurrentElement(constructor, () { |
| 1463 assert(functionBuilder == | 1484 assert(functionBuilder == |
| 1464 systemBuilder.lookupConstructorInitializerByElement(constructor)); | 1485 systemBuilder.lookupConstructorInitializerByElement(constructor)); |
| 1465 context.compiler.reportVerboseInfo( | 1486 context.compiler.reportVerboseInfo( |
| 1466 constructor, 'Compiling constructor initializer $constructor'); | 1487 constructor, 'Compiling constructor initializer $constructor'); |
| 1467 | 1488 |
| 1468 TreeElements elements = constructor.resolvedAst.elements; | 1489 TreeElements elements = constructor.resolvedAst.elements; |
| 1469 | 1490 |
| 1470 // TODO(ahe): We shouldn't create a registry, but we have to as long as | 1491 // TODO(ahe): We shouldn't create a registry, but we have to as long as |
| 1471 // the enqueuer doesn't support elements with more than one compilation | 1492 // the enqueuer doesn't support elements with more than one compilation |
| 1472 // artifact. | 1493 // artifact. |
| 1473 FletchRegistry registry = | 1494 FletchRegistry registry = new FletchRegistry(compiler); |
| 1474 new FletchRegistry(compiler, elements); | |
| 1475 | 1495 |
| 1476 FletchClassBuilder classBuilder = | 1496 FletchClassBuilder classBuilder = |
| 1477 registerClassElement(constructor.enclosingClass.declaration); | 1497 registerClassElement(constructor.enclosingClass.declaration); |
| 1478 | 1498 |
| 1479 ClosureEnvironment closureEnvironment = | 1499 ClosureEnvironment closureEnvironment = |
| 1480 createClosureEnvironment(constructor, elements); | 1500 createClosureEnvironment(constructor, elements); |
| 1481 | 1501 |
| 1482 ConstructorCodegen codegen = new ConstructorCodegen( | 1502 ConstructorCodegen codegen = new ConstructorCodegen( |
| 1483 functionBuilder, | 1503 functionBuilder, |
| 1484 context, | 1504 context, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1510 int makeSetter(int fieldIndex) { | 1530 int makeSetter(int fieldIndex) { |
| 1511 return systemBuilder.getSetterByFieldIndex(fieldIndex); | 1531 return systemBuilder.getSetterByFieldIndex(fieldIndex); |
| 1512 } | 1532 } |
| 1513 | 1533 |
| 1514 void generateUnimplementedError( | 1534 void generateUnimplementedError( |
| 1515 Spannable spannable, | 1535 Spannable spannable, |
| 1516 String reason, | 1536 String reason, |
| 1517 FletchFunctionBuilder function, | 1537 FletchFunctionBuilder function, |
| 1518 {bool suppressHint: false}) { | 1538 {bool suppressHint: false}) { |
| 1519 if (!suppressHint) { | 1539 if (!suppressHint) { |
| 1520 compiler.reportHint( | 1540 compiler.reporter.reportHintMessage( |
| 1521 spannable, MessageKind.GENERIC, {'text': reason}); | 1541 spannable, MessageKind.GENERIC, {'text': reason}); |
| 1522 } | 1542 } |
| 1523 var constString = constantSystem.createString( | 1543 var constString = constantSystem.createString( |
| 1524 new DartString.literal(reason)); | 1544 new DartString.literal(reason)); |
| 1525 context.markConstantUsed(constString); | 1545 context.markConstantUsed(constString); |
| 1526 function | 1546 function |
| 1527 ..assembler.loadConst(function.allocateConstant(constString)) | 1547 ..assembler.loadConst(function.allocateConstant(constString)) |
| 1528 ..assembler.emitThrow(); | 1548 ..assembler.emitThrow(); |
| 1529 } | 1549 } |
| 1530 | 1550 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1607 /// us to compile a generative constructor (see [codegen]), and track | 1627 /// us to compile a generative constructor (see [codegen]), and track |
| 1608 /// constructor initializers in a separate queue. | 1628 /// constructor initializers in a separate queue. |
| 1609 void compilePendingConstructorInitializers() { | 1629 void compilePendingConstructorInitializers() { |
| 1610 while (pendingConstructorInitializers.isNotEmpty) { | 1630 while (pendingConstructorInitializers.isNotEmpty) { |
| 1611 compileConstructorInitializer( | 1631 compileConstructorInitializer( |
| 1612 pendingConstructorInitializers.removeLast()); | 1632 pendingConstructorInitializers.removeLast()); |
| 1613 } | 1633 } |
| 1614 } | 1634 } |
| 1615 | 1635 |
| 1616 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { | 1636 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { |
| 1617 if (!enqueuer.isResolutionQueue) { | 1637 if (enqueuer is! ResolutionEnqueuer) { |
| 1618 compilePendingConstructorInitializers(); | 1638 compilePendingConstructorInitializers(); |
| 1619 } | 1639 } |
| 1620 return super.onQueueEmpty(enqueuer, recentClasses); | 1640 return true; |
| 1621 } | 1641 } |
| 1622 | 1642 |
| 1623 FletchEnqueueTask makeEnqueuer() => new FletchEnqueueTask(compiler); | 1643 FletchEnqueueTask makeEnqueuer() => new FletchEnqueueTask(compiler); |
| 1624 | 1644 |
| 1625 static bool isExactParameterMatch( | 1645 static bool isExactParameterMatch( |
| 1626 FunctionSignature signature, | 1646 FunctionSignature signature, |
| 1627 CallStructure callStructure) { | 1647 CallStructure callStructure) { |
| 1628 if (!callStructure.signatureApplies(signature)) { | 1648 if (!callStructure.signatureApplies(signature)) { |
| 1629 return false; | 1649 return false; |
| 1630 } | 1650 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1649 int index = 0; | 1669 int index = 0; |
| 1650 for (var parameter in signature.orderedOptionalParameters) { | 1670 for (var parameter in signature.orderedOptionalParameters) { |
| 1651 if (parameter.name != callStructure.namedArguments[index++]) return false; | 1671 if (parameter.name != callStructure.namedArguments[index++]) return false; |
| 1652 } | 1672 } |
| 1653 return true; | 1673 return true; |
| 1654 } | 1674 } |
| 1655 | 1675 |
| 1656 static FletchBackend newInstance(FletchCompilerImplementation compiler) { | 1676 static FletchBackend newInstance(FletchCompilerImplementation compiler) { |
| 1657 return new FletchBackend(compiler); | 1677 return new FletchBackend(compiler); |
| 1658 } | 1678 } |
| 1679 |
| 1680 Uri resolvePatchUri(String libraryName, Uri libraryRoot) { |
| 1681 throw "Not implemented"; |
| 1682 } |
| 1683 |
| 1684 } |
| 1685 |
| 1686 class FletchImpactTransformer extends ImpactTransformer { |
| 1687 final FletchBackend backend; |
| 1688 |
| 1689 FletchImpactTransformer(this.backend); |
| 1690 |
| 1691 @override |
| 1692 WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) { |
| 1693 FletchRegistry registry = new FletchRegistry(backend.compiler); |
| 1694 TransformedWorldImpact transformed = |
| 1695 new TransformedWorldImpact(worldImpact); |
| 1696 |
| 1697 if (worldImpact.constSymbolNames.isNotEmpty) { |
| 1698 ClassElement symbolClass = |
| 1699 backend.compiler.coreClasses.symbolClass.declaration; |
| 1700 transformed.registerTypeUse( |
| 1701 new TypeUse.instantiation(symbolClass.rawType)); |
| 1702 transformed.registerStaticUse( |
| 1703 new StaticUse.foreignUse( |
| 1704 symbolClass.lookupConstructor(""))); |
| 1705 } |
| 1706 |
| 1707 for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) { |
| 1708 if (mapLiteralUse.isConstant) continue; |
| 1709 transformed.registerTypeUse( |
| 1710 new TypeUse.instantiation(backend.mapImplementation.rawType)); |
| 1711 transformed.registerStaticUse( |
| 1712 new StaticUse.constructorInvoke( |
| 1713 backend.mapImplementation.lookupConstructor(""), |
| 1714 CallStructure.NO_ARGS)); |
| 1715 } |
| 1716 return transformed; |
| 1717 } |
| 1718 |
| 1719 @override |
| 1720 transformCodegenImpact(impact) => throw "unimplemented"; |
| 1659 } | 1721 } |
| 1660 | 1722 |
| 1661 bool isLocalFunction(Element element) { | 1723 bool isLocalFunction(Element element) { |
| 1662 if (!element.isFunction) return false; | 1724 if (!element.isFunction) return false; |
| 1663 if (element is ExecutableElement) { | 1725 if (element is ExecutableElement) { |
| 1664 return element.memberContext != element; | 1726 return element.memberContext != element; |
| 1665 } | 1727 } |
| 1666 return false; | 1728 return false; |
| 1667 } | 1729 } |
| 1668 | 1730 |
| 1669 Name memberName(AstElement element) { | 1731 Name memberName(AstElement element) { |
| 1670 if (isLocalFunction(element)) return null; | 1732 if (isLocalFunction(element)) return null; |
| 1671 MemberElement member = element; | 1733 MemberElement member = element; |
| 1672 return member.memberName; | 1734 return member.memberName; |
| 1673 } | 1735 } |
| OLD | NEW |