| OLD | NEW |
| 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dartino 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 dartino_compiler.dartino_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/common/backend_api.dart' show | 13 import 'package:compiler/src/common/backend_api.dart' show |
| 14 Backend, | 14 Backend, |
| 15 ImpactTransformer; | 15 ImpactTransformer; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 | 97 |
| 98 import 'package:compiler/src/resolution/tree_elements.dart' show | 98 import 'package:compiler/src/resolution/tree_elements.dart' show |
| 99 TreeElements; | 99 TreeElements; |
| 100 | 100 |
| 101 import 'package:compiler/src/library_loader.dart' show | 101 import 'package:compiler/src/library_loader.dart' show |
| 102 LibraryLoader; | 102 LibraryLoader; |
| 103 | 103 |
| 104 import 'package:persistent/persistent.dart' show | 104 import 'package:persistent/persistent.dart' show |
| 105 PersistentMap; | 105 PersistentMap; |
| 106 | 106 |
| 107 import 'fletch_function_builder.dart' show | 107 import 'dartino_function_builder.dart' show |
| 108 FletchFunctionBuilder; | 108 DartinoFunctionBuilder; |
| 109 | 109 |
| 110 import 'fletch_class_builder.dart' show | 110 import 'dartino_class_builder.dart' show |
| 111 FletchClassBuilder; | 111 DartinoClassBuilder; |
| 112 | 112 |
| 113 import 'fletch_system_builder.dart' show | 113 import 'dartino_system_builder.dart' show |
| 114 FletchSystemBuilder; | 114 DartinoSystemBuilder; |
| 115 | 115 |
| 116 import '../incremental_backend.dart' show | 116 import '../incremental_backend.dart' show |
| 117 IncrementalFletchBackend; | 117 IncrementalDartinoBackend; |
| 118 | 118 |
| 119 import 'fletch_enqueuer.dart' show | 119 import 'dartino_enqueuer.dart' show |
| 120 FletchEnqueueTask, | 120 DartinoEnqueueTask, |
| 121 shouldReportEnqueuingOfElement; | 121 shouldReportEnqueuingOfElement; |
| 122 | 122 |
| 123 import 'fletch_registry.dart' show | 123 import 'dartino_registry.dart' show |
| 124 ClosureKind, | 124 ClosureKind, |
| 125 FletchRegistry; | 125 DartinoRegistry; |
| 126 | 126 |
| 127 import 'diagnostic.dart' show | 127 import 'diagnostic.dart' show |
| 128 throwInternalError; | 128 throwInternalError; |
| 129 | 129 |
| 130 import 'package:compiler/src/common/names.dart' show | 130 import 'package:compiler/src/common/names.dart' show |
| 131 Identifiers, | 131 Identifiers, |
| 132 Names; | 132 Names; |
| 133 | 133 |
| 134 import 'package:compiler/src/universe/world_impact.dart' show | 134 import 'package:compiler/src/universe/world_impact.dart' show |
| 135 TransformedWorldImpact, | 135 TransformedWorldImpact, |
| 136 WorldImpact, | 136 WorldImpact, |
| 137 WorldImpactBuilder; | 137 WorldImpactBuilder; |
| 138 | 138 |
| 139 import 'class_debug_info.dart'; | 139 import 'class_debug_info.dart'; |
| 140 import 'codegen_visitor.dart'; | 140 import 'codegen_visitor.dart'; |
| 141 import 'debug_info.dart'; | 141 import 'debug_info.dart'; |
| 142 import 'debug_info_constructor_codegen.dart'; | 142 import 'debug_info_constructor_codegen.dart'; |
| 143 import 'debug_info_function_codegen.dart'; | 143 import 'debug_info_function_codegen.dart'; |
| 144 import 'debug_info_lazy_field_initializer_codegen.dart'; | 144 import 'debug_info_lazy_field_initializer_codegen.dart'; |
| 145 import 'fletch_context.dart'; | 145 import 'dartino_context.dart'; |
| 146 import 'fletch_selector.dart'; | 146 import 'dartino_selector.dart'; |
| 147 import 'function_codegen.dart'; | 147 import 'function_codegen.dart'; |
| 148 import 'lazy_field_initializer_codegen.dart'; | 148 import 'lazy_field_initializer_codegen.dart'; |
| 149 import 'constructor_codegen.dart'; | 149 import 'constructor_codegen.dart'; |
| 150 import 'closure_environment.dart'; | 150 import 'closure_environment.dart'; |
| 151 | 151 |
| 152 import '../bytecodes.dart'; | 152 import '../bytecodes.dart'; |
| 153 import '../vm_commands.dart'; | 153 import '../vm_commands.dart'; |
| 154 import '../fletch_system.dart'; | 154 import '../dartino_system.dart'; |
| 155 import 'package:compiler/src/common/resolution.dart'; | 155 import 'package:compiler/src/common/resolution.dart'; |
| 156 | 156 |
| 157 const FletchSystem BASE_FLETCH_SYSTEM = const FletchSystem( | 157 const DartinoSystem BASE_DARTINO_SYSTEM = const DartinoSystem( |
| 158 const PersistentMap<int, FletchFunction>(), | 158 const PersistentMap<int, DartinoFunction>(), |
| 159 const PersistentMap<Element, FletchFunction>(), | 159 const PersistentMap<Element, DartinoFunction>(), |
| 160 const PersistentMap<ConstructorElement, FletchFunction>(), | 160 const PersistentMap<ConstructorElement, DartinoFunction>(), |
| 161 const PersistentMap<int, int>(), | 161 const PersistentMap<int, int>(), |
| 162 const PersistentMap<int, FletchClass>(), | 162 const PersistentMap<int, DartinoClass>(), |
| 163 const PersistentMap<ClassElement, FletchClass>(), | 163 const PersistentMap<ClassElement, DartinoClass>(), |
| 164 const PersistentMap<int, FletchConstant>(), | 164 const PersistentMap<int, DartinoConstant>(), |
| 165 const PersistentMap<ConstantValue, FletchConstant>(), | 165 const PersistentMap<ConstantValue, DartinoConstant>(), |
| 166 const PersistentMap<int, String>(), | 166 const PersistentMap<int, String>(), |
| 167 const PersistentMap<int, int>(), | 167 const PersistentMap<int, int>(), |
| 168 const PersistentMap<int, int>(), | 168 const PersistentMap<int, int>(), |
| 169 const PersistentMap<ParameterStubSignature, FletchFunction>()); | 169 const PersistentMap<ParameterStubSignature, DartinoFunction>()); |
| 170 | 170 |
| 171 class FletchBackend extends Backend | 171 class DartinoBackend extends Backend |
| 172 implements IncrementalFletchBackend { | 172 implements IncrementalDartinoBackend { |
| 173 static const String growableListName = '_GrowableList'; | 173 static const String growableListName = '_GrowableList'; |
| 174 static const String constantListName = '_ConstantList'; | 174 static const String constantListName = '_ConstantList'; |
| 175 static const String constantByteListName = '_ConstantByteList'; | 175 static const String constantByteListName = '_ConstantByteList'; |
| 176 static const String constantMapName = '_ConstantMap'; | 176 static const String constantMapName = '_ConstantMap'; |
| 177 static const String fletchNoSuchMethodErrorName = 'FletchNoSuchMethodError'; | 177 static const String dartinoNoSuchMethodErrorName = 'DartinoNoSuchMethodError'; |
| 178 static const String noSuchMethodName = '_noSuchMethod'; | 178 static const String noSuchMethodName = '_noSuchMethod'; |
| 179 static const String noSuchMethodTrampolineName = '_noSuchMethodTrampoline'; | 179 static const String noSuchMethodTrampolineName = '_noSuchMethodTrampoline'; |
| 180 | 180 |
| 181 final FletchContext context; | 181 final DartinoContext context; |
| 182 | 182 |
| 183 final DartConstantTask constantCompilerTask; | 183 final DartConstantTask constantCompilerTask; |
| 184 | 184 |
| 185 /// Constructors that need to have an initilizer compiled. See | 185 /// Constructors that need to have an initilizer compiled. See |
| 186 /// [compilePendingConstructorInitializers]. | 186 /// [compilePendingConstructorInitializers]. |
| 187 final Queue<FletchFunctionBuilder> pendingConstructorInitializers = | 187 final Queue<DartinoFunctionBuilder> pendingConstructorInitializers = |
| 188 new Queue<FletchFunctionBuilder>(); | 188 new Queue<DartinoFunctionBuilder>(); |
| 189 | 189 |
| 190 final Set<FunctionElement> externals = new Set<FunctionElement>(); | 190 final Set<FunctionElement> externals = new Set<FunctionElement>(); |
| 191 | 191 |
| 192 // TODO(ahe): This should be queried from World. | 192 // TODO(ahe): This should be queried from World. |
| 193 final Map<ClassElement, Set<ClassElement>> directSubclasses = | 193 final Map<ClassElement, Set<ClassElement>> directSubclasses = |
| 194 <ClassElement, Set<ClassElement>>{}; | 194 <ClassElement, Set<ClassElement>>{}; |
| 195 | 195 |
| 196 /// Set of classes that have special meaning to the Fletch VM. They're | 196 /// Set of classes that have special meaning to the Dartino VM. They're |
| 197 /// created using [PushBuiltinClass] instead of [PushNewClass]. | 197 /// created using [PushBuiltinClass] instead of [PushNewClass]. |
| 198 // TODO(ahe): Move this to FletchSystem? | 198 // TODO(ahe): Move this to DartinoSystem? |
| 199 final Set<ClassElement> builtinClasses = new Set<ClassElement>(); | 199 final Set<ClassElement> builtinClasses = new Set<ClassElement>(); |
| 200 | 200 |
| 201 // TODO(ahe): This should be invalidated by a new [FletchSystem]. | 201 // TODO(ahe): This should be invalidated by a new [DartinoSystem]. |
| 202 final Map<MemberElement, ClosureEnvironment> closureEnvironments = | 202 final Map<MemberElement, ClosureEnvironment> closureEnvironments = |
| 203 <MemberElement, ClosureEnvironment>{}; | 203 <MemberElement, ClosureEnvironment>{}; |
| 204 | 204 |
| 205 // TODO(ahe): This should be moved to [FletchSystem]. | 205 // TODO(ahe): This should be moved to [DartinoSystem]. |
| 206 final Map<FunctionElement, FletchClassBuilder> closureClasses = | 206 final Map<FunctionElement, DartinoClassBuilder> closureClasses = |
| 207 <FunctionElement, FletchClassBuilder>{}; | 207 <FunctionElement, DartinoClassBuilder>{}; |
| 208 | 208 |
| 209 // TODO(ahe): This should be moved to [FletchSystem]. | 209 // TODO(ahe): This should be moved to [DartinoSystem]. |
| 210 final Map<FieldElement, FletchFunctionBuilder> lazyFieldInitializers = | 210 final Map<FieldElement, DartinoFunctionBuilder> lazyFieldInitializers = |
| 211 <FieldElement, FletchFunctionBuilder>{}; | 211 <FieldElement, DartinoFunctionBuilder>{}; |
| 212 | 212 |
| 213 // TODO(ahe): This should be moved to [FletchSystem]. | 213 // TODO(ahe): This should be moved to [DartinoSystem]. |
| 214 Map<FletchClassBuilder, FletchFunctionBuilder> tearoffFunctions; | 214 Map<DartinoClassBuilder, DartinoFunctionBuilder> tearoffFunctions; |
| 215 | 215 |
| 216 FletchCompilerImplementation get compiler => super.compiler; | 216 DartinoCompilerImplementation get compiler => super.compiler; |
| 217 | 217 |
| 218 LibraryElement fletchSystemLibrary; | 218 LibraryElement dartinoSystemLibrary; |
| 219 LibraryElement fletchFFILibrary; | 219 LibraryElement dartinoFFILibrary; |
| 220 LibraryElement collectionLibrary; | 220 LibraryElement collectionLibrary; |
| 221 LibraryElement mathLibrary; | 221 LibraryElement mathLibrary; |
| 222 LibraryElement get asyncLibrary => compiler.asyncLibrary; | 222 LibraryElement get asyncLibrary => compiler.asyncLibrary; |
| 223 LibraryElement fletchLibrary; | 223 LibraryElement dartinoLibrary; |
| 224 | 224 |
| 225 FunctionElement fletchSystemEntry; | 225 FunctionElement dartinoSystemEntry; |
| 226 | 226 |
| 227 FunctionElement fletchExternalInvokeMain; | 227 FunctionElement dartinoExternalInvokeMain; |
| 228 | 228 |
| 229 FunctionElement fletchExternalYield; | 229 FunctionElement dartinoExternalYield; |
| 230 | 230 |
| 231 FunctionElement fletchExternalNativeError; | 231 FunctionElement dartinoExternalNativeError; |
| 232 | 232 |
| 233 FunctionElement fletchExternalCoroutineChange; | 233 FunctionElement dartinoExternalCoroutineChange; |
| 234 | 234 |
| 235 FunctionElement fletchUnresolved; | 235 FunctionElement dartinoUnresolved; |
| 236 FunctionElement fletchCompileError; | 236 FunctionElement dartinoCompileError; |
| 237 | 237 |
| 238 FletchClassBuilder compiledObjectClass; | 238 DartinoClassBuilder compiledObjectClass; |
| 239 | 239 |
| 240 ClassElement smiClass; | 240 ClassElement smiClass; |
| 241 ClassElement mintClass; | 241 ClassElement mintClass; |
| 242 ClassElement growableListClass; | 242 ClassElement growableListClass; |
| 243 ClassElement fletchNoSuchMethodErrorClass; | 243 ClassElement dartinoNoSuchMethodErrorClass; |
| 244 ClassElement bigintClass; | 244 ClassElement bigintClass; |
| 245 ClassElement uint32DigitsClass; | 245 ClassElement uint32DigitsClass; |
| 246 | 246 |
| 247 FletchClassBuilder compiledClosureClass; | 247 DartinoClassBuilder compiledClosureClass; |
| 248 | 248 |
| 249 /// Holds a reference to the class Coroutine if it exists. | 249 /// Holds a reference to the class Coroutine if it exists. |
| 250 ClassElement coroutineClass; | 250 ClassElement coroutineClass; |
| 251 | 251 |
| 252 FletchSystemBuilder systemBuilder; | 252 DartinoSystemBuilder systemBuilder; |
| 253 | 253 |
| 254 final Set<FunctionElement> alwaysEnqueue = new Set<FunctionElement>(); | 254 final Set<FunctionElement> alwaysEnqueue = new Set<FunctionElement>(); |
| 255 | 255 |
| 256 FletchImpactTransformer impactTransformer; | 256 DartinoImpactTransformer impactTransformer; |
| 257 | 257 |
| 258 FletchBackend(FletchCompilerImplementation compiler) | 258 DartinoBackend(DartinoCompilerImplementation compiler) |
| 259 : this.context = compiler.context, | 259 : this.context = compiler.context, |
| 260 this.constantCompilerTask = new DartConstantTask(compiler), | 260 this.constantCompilerTask = new DartConstantTask(compiler), |
| 261 this.systemBuilder = new FletchSystemBuilder(BASE_FLETCH_SYSTEM), | 261 this.systemBuilder = new DartinoSystemBuilder(BASE_DARTINO_SYSTEM), |
| 262 super(compiler) { | 262 super(compiler) { |
| 263 this.impactTransformer = new FletchImpactTransformer(this); | 263 this.impactTransformer = new DartinoImpactTransformer(this); |
| 264 } | 264 } |
| 265 | 265 |
| 266 void newSystemBuilder(FletchSystem predecessorSystem) { | 266 void newSystemBuilder(DartinoSystem predecessorSystem) { |
| 267 systemBuilder = new FletchSystemBuilder(predecessorSystem); | 267 systemBuilder = new DartinoSystemBuilder(predecessorSystem); |
| 268 } | 268 } |
| 269 | 269 |
| 270 // TODO(zarah): Move to FletchSystemBuilder. | 270 // TODO(zarah): Move to DartinoSystemBuilder. |
| 271 FletchClassBuilder getClassBuilderOfExistingClass(int id) { | 271 DartinoClassBuilder getClassBuilderOfExistingClass(int id) { |
| 272 FletchClassBuilder classBuilder = systemBuilder.lookupClassBuilder(id); | 272 DartinoClassBuilder classBuilder = systemBuilder.lookupClassBuilder(id); |
| 273 if (classBuilder != null) return classBuilder; | 273 if (classBuilder != null) return classBuilder; |
| 274 FletchClass klass = systemBuilder.lookupClass(id); | 274 DartinoClass klass = systemBuilder.lookupClass(id); |
| 275 if (klass.element != null) return registerClassElement(klass.element); | 275 if (klass.element != null) return registerClassElement(klass.element); |
| 276 // [klass] is a tearoff class | 276 // [klass] is a tearoff class |
| 277 return systemBuilder.newPatchClassBuilder(id, compiledClosureClass); | 277 return systemBuilder.newPatchClassBuilder(id, compiledClosureClass); |
| 278 } | 278 } |
| 279 | 279 |
| 280 FletchClassBuilder registerClassElement(ClassElement element) { | 280 DartinoClassBuilder registerClassElement(ClassElement element) { |
| 281 if (element == null) return null; | 281 if (element == null) return null; |
| 282 assert(element.isDeclaration); | 282 assert(element.isDeclaration); |
| 283 | 283 |
| 284 FletchClassBuilder classBuilder = | 284 DartinoClassBuilder classBuilder = |
| 285 systemBuilder.lookupClassBuilderByElement(element); | 285 systemBuilder.lookupClassBuilderByElement(element); |
| 286 if (classBuilder != null) return classBuilder; | 286 if (classBuilder != null) return classBuilder; |
| 287 | 287 |
| 288 directSubclasses[element] = new Set<ClassElement>(); | 288 directSubclasses[element] = new Set<ClassElement>(); |
| 289 FletchClassBuilder superclass = registerClassElement(element.superclass); | 289 DartinoClassBuilder superclass = registerClassElement(element.superclass); |
| 290 if (superclass != null) { | 290 if (superclass != null) { |
| 291 Set<ClassElement> subclasses = directSubclasses[element.superclass]; | 291 Set<ClassElement> subclasses = directSubclasses[element.superclass]; |
| 292 subclasses.add(element); | 292 subclasses.add(element); |
| 293 } | 293 } |
| 294 classBuilder = systemBuilder.newClassBuilder( | 294 classBuilder = systemBuilder.newClassBuilder( |
| 295 element, superclass, builtinClasses.contains(element)); | 295 element, superclass, builtinClasses.contains(element)); |
| 296 | 296 |
| 297 // TODO(ajohnsen): Currently, the FletchRegistry does not enqueue fields. | 297 // TODO(ajohnsen): Currently, the DartinoRegistry does not enqueue fields. |
| 298 // This is a workaround, where we basically add getters for all fields. | 298 // This is a workaround, where we basically add getters for all fields. |
| 299 classBuilder.updateImplicitAccessors(this); | 299 classBuilder.updateImplicitAccessors(this); |
| 300 | 300 |
| 301 Element callMember = element.lookupLocalMember(Identifiers.call); | 301 Element callMember = element.lookupLocalMember(Identifiers.call); |
| 302 if (callMember != null && callMember.isFunction) { | 302 if (callMember != null && callMember.isFunction) { |
| 303 FunctionElement function = callMember; | 303 FunctionElement function = callMember; |
| 304 classBuilder.createIsFunctionEntry( | 304 classBuilder.createIsFunctionEntry( |
| 305 this, function.functionSignature.parameterCount); | 305 this, function.functionSignature.parameterCount); |
| 306 } | 306 } |
| 307 return classBuilder; | 307 return classBuilder; |
| 308 } | 308 } |
| 309 | 309 |
| 310 FletchClassBuilder createCallableStubClass( | 310 DartinoClassBuilder createCallableStubClass( |
| 311 int fields, int arity, FletchClassBuilder superclass) { | 311 int fields, int arity, DartinoClassBuilder superclass) { |
| 312 FletchClassBuilder classBuilder = systemBuilder.newClassBuilder( | 312 DartinoClassBuilder classBuilder = systemBuilder.newClassBuilder( |
| 313 null, superclass, false, extraFields: fields); | 313 null, superclass, false, extraFields: fields); |
| 314 classBuilder.createIsFunctionEntry(this, arity); | 314 classBuilder.createIsFunctionEntry(this, arity); |
| 315 return classBuilder; | 315 return classBuilder; |
| 316 } | 316 } |
| 317 | 317 |
| 318 List<CompilerTask> get tasks => <CompilerTask>[]; | 318 List<CompilerTask> get tasks => <CompilerTask>[]; |
| 319 | 319 |
| 320 ConstantSystem get constantSystem { | 320 ConstantSystem get constantSystem { |
| 321 return constantCompilerTask.constantCompiler.constantSystem; | 321 return constantCompilerTask.constantCompiler.constantSystem; |
| 322 } | 322 } |
| 323 | 323 |
| 324 BackendConstantEnvironment get constants => constantCompilerTask; | 324 BackendConstantEnvironment get constants => constantCompilerTask; |
| 325 | 325 |
| 326 bool classNeedsRti(ClassElement cls) => false; | 326 bool classNeedsRti(ClassElement cls) => false; |
| 327 | 327 |
| 328 bool methodNeedsRti(FunctionElement function) => false; | 328 bool methodNeedsRti(FunctionElement function) => false; |
| 329 | 329 |
| 330 void enqueueHelpers(ResolutionEnqueuer world, Registry incomingRegistry) { | 330 void enqueueHelpers(ResolutionEnqueuer world, Registry incomingRegistry) { |
| 331 FletchRegistry registry = new FletchRegistry(compiler); | 331 DartinoRegistry registry = new DartinoRegistry(compiler); |
| 332 compiler.patchAnnotationClass = patchAnnotationClass; | 332 compiler.patchAnnotationClass = patchAnnotationClass; |
| 333 | 333 |
| 334 bool hasMissingHelpers = false; | 334 bool hasMissingHelpers = false; |
| 335 loadHelperMethods((String name) { | 335 loadHelperMethods((String name) { |
| 336 LibraryElement library = fletchSystemLibrary; | 336 LibraryElement library = dartinoSystemLibrary; |
| 337 Element helper = library.findLocal(name); | 337 Element helper = library.findLocal(name); |
| 338 // TODO(ahe): Make it cleaner. | 338 // TODO(ahe): Make it cleaner. |
| 339 if (helper != null && helper.isAbstractField) { | 339 if (helper != null && helper.isAbstractField) { |
| 340 AbstractFieldElement abstractField = helper; | 340 AbstractFieldElement abstractField = helper; |
| 341 helper = abstractField.getter; | 341 helper = abstractField.getter; |
| 342 } | 342 } |
| 343 if (helper == null) { | 343 if (helper == null) { |
| 344 hasMissingHelpers = true; | 344 hasMissingHelpers = true; |
| 345 compiler.reporter.reportErrorMessage( | 345 compiler.reporter.reportErrorMessage( |
| 346 library, MessageKind.GENERIC, | 346 library, MessageKind.GENERIC, |
| 347 {'text': "Required implementation method '$name' not found."}); | 347 {'text': "Required implementation method '$name' not found."}); |
| 348 } | 348 } |
| 349 return helper; | 349 return helper; |
| 350 }); | 350 }); |
| 351 if (hasMissingHelpers) { | 351 if (hasMissingHelpers) { |
| 352 throwInternalError( | 352 throwInternalError( |
| 353 "Some implementation methods are missing, see details above"); | 353 "Some implementation methods are missing, see details above"); |
| 354 } | 354 } |
| 355 world.registerStaticUse( | 355 world.registerStaticUse( |
| 356 new StaticUse.staticInvoke(fletchCompileError, CallStructure.ONE_ARG)); | 356 new StaticUse.staticInvoke(dartinoCompileError, CallStructure.ONE_ARG)); |
| 357 world.registerStaticUse( | 357 world.registerStaticUse( |
| 358 new StaticUse.staticInvoke(fletchSystemEntry, CallStructure.ONE_ARG)); | 358 new StaticUse.staticInvoke(dartinoSystemEntry, CallStructure.ONE_ARG)); |
| 359 world.registerStaticUse( | 359 world.registerStaticUse( |
| 360 new StaticUse.staticInvoke(fletchUnresolved, CallStructure.ONE_ARG)); | 360 new StaticUse.staticInvoke(dartinoUnresolved, CallStructure.ONE_ARG)); |
| 361 | 361 |
| 362 loadHelperClasses(( | 362 loadHelperClasses(( |
| 363 String name, | 363 String name, |
| 364 LibraryElement library, | 364 LibraryElement library, |
| 365 {bool builtin: false}) { | 365 {bool builtin: false}) { |
| 366 var classImpl = library.findLocal(name); | 366 var classImpl = library.findLocal(name); |
| 367 if (classImpl == null) classImpl = library.implementation.find(name); | 367 if (classImpl == null) classImpl = library.implementation.find(name); |
| 368 if (classImpl == null) { | 368 if (classImpl == null) { |
| 369 compiler.reporter.reportErrorMessage( | 369 compiler.reporter.reportErrorMessage( |
| 370 library, MessageKind.GENERIC, | 370 library, MessageKind.GENERIC, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 | 424 |
| 425 void loadHelperMethods( | 425 void loadHelperMethods( |
| 426 FunctionElement findHelper(String name)) { | 426 FunctionElement findHelper(String name)) { |
| 427 | 427 |
| 428 FunctionElement findExternal(String name) { | 428 FunctionElement findExternal(String name) { |
| 429 FunctionElement helper = findHelper(name); | 429 FunctionElement helper = findHelper(name); |
| 430 if (helper != null) externals.add(helper); | 430 if (helper != null) externals.add(helper); |
| 431 return helper; | 431 return helper; |
| 432 } | 432 } |
| 433 | 433 |
| 434 fletchSystemEntry = findHelper('entry'); | 434 dartinoSystemEntry = findHelper('entry'); |
| 435 fletchExternalInvokeMain = findExternal('invokeMain'); | 435 dartinoExternalInvokeMain = findExternal('invokeMain'); |
| 436 fletchExternalYield = findExternal('yield'); | 436 dartinoExternalYield = findExternal('yield'); |
| 437 fletchExternalCoroutineChange = findExternal('coroutineChange'); | 437 dartinoExternalCoroutineChange = findExternal('coroutineChange'); |
| 438 fletchExternalNativeError = findExternal('nativeError'); | 438 dartinoExternalNativeError = findExternal('nativeError'); |
| 439 fletchUnresolved = findExternal('unresolved'); | 439 dartinoUnresolved = findExternal('unresolved'); |
| 440 fletchCompileError = findExternal('compileError'); | 440 dartinoCompileError = findExternal('compileError'); |
| 441 } | 441 } |
| 442 | 442 |
| 443 void loadHelperClasses( | 443 void loadHelperClasses( |
| 444 FletchClassBuilder loadClass( | 444 DartinoClassBuilder loadClass( |
| 445 String name, | 445 String name, |
| 446 LibraryElement library, | 446 LibraryElement library, |
| 447 {bool builtin})) { | 447 {bool builtin})) { |
| 448 compiledObjectClass = | 448 compiledObjectClass = |
| 449 loadClass("Object", compiler.coreLibrary, builtin: true); | 449 loadClass("Object", compiler.coreLibrary, builtin: true); |
| 450 compiledClosureClass = | 450 compiledClosureClass = |
| 451 loadClass("_TearOffClosure", compiler.coreLibrary, builtin: true); | 451 loadClass("_TearOffClosure", compiler.coreLibrary, builtin: true); |
| 452 smiClass = loadClass("_Smi", compiler.coreLibrary, builtin: true)?.element; | 452 smiClass = loadClass("_Smi", compiler.coreLibrary, builtin: true)?.element; |
| 453 mintClass = | 453 mintClass = |
| 454 loadClass("_Mint", compiler.coreLibrary, builtin: true)?.element; | 454 loadClass("_Mint", compiler.coreLibrary, builtin: true)?.element; |
| 455 loadClass("_OneByteString", compiler.coreLibrary, builtin: true); | 455 loadClass("_OneByteString", compiler.coreLibrary, builtin: true); |
| 456 loadClass("_TwoByteString", compiler.coreLibrary, builtin: true); | 456 loadClass("_TwoByteString", compiler.coreLibrary, builtin: true); |
| 457 // TODO(ahe): Register _ConstantList through ResolutionCallbacks. | 457 // TODO(ahe): Register _ConstantList through ResolutionCallbacks. |
| 458 loadClass(constantListName, fletchSystemLibrary, builtin: true); | 458 loadClass(constantListName, dartinoSystemLibrary, builtin: true); |
| 459 loadClass(constantByteListName, fletchSystemLibrary, builtin: true); | 459 loadClass(constantByteListName, dartinoSystemLibrary, builtin: true); |
| 460 loadClass(constantMapName, fletchSystemLibrary, builtin: true); | 460 loadClass(constantMapName, dartinoSystemLibrary, builtin: true); |
| 461 loadClass("_DoubleImpl", compiler.coreLibrary, builtin: true); | 461 loadClass("_DoubleImpl", compiler.coreLibrary, builtin: true); |
| 462 loadClass("Null", compiler.coreLibrary, builtin: true); | 462 loadClass("Null", compiler.coreLibrary, builtin: true); |
| 463 loadClass("bool", compiler.coreLibrary, builtin: true); | 463 loadClass("bool", compiler.coreLibrary, builtin: true); |
| 464 loadClass("StackOverflowError", compiler.coreLibrary, builtin: true); | 464 loadClass("StackOverflowError", compiler.coreLibrary, builtin: true); |
| 465 loadClass("Port", fletchLibrary, builtin: true); | 465 loadClass("Port", dartinoLibrary, builtin: true); |
| 466 loadClass("Process", fletchLibrary, builtin: true); | 466 loadClass("Process", dartinoLibrary, builtin: true); |
| 467 loadClass("ProcessDeath", fletchLibrary, builtin: true); | 467 loadClass("ProcessDeath", dartinoLibrary, builtin: true); |
| 468 loadClass("ForeignMemory", fletchFFILibrary, builtin: true); | 468 loadClass("ForeignMemory", dartinoFFILibrary, builtin: true); |
| 469 if (context.enableBigint) { | 469 if (context.enableBigint) { |
| 470 bigintClass = loadClass("_Bigint", compiler.coreLibrary)?.element; | 470 bigintClass = loadClass("_Bigint", compiler.coreLibrary)?.element; |
| 471 uint32DigitsClass = | 471 uint32DigitsClass = |
| 472 loadClass("_Uint32Digits", compiler.coreLibrary)?.element; | 472 loadClass("_Uint32Digits", compiler.coreLibrary)?.element; |
| 473 } | 473 } |
| 474 growableListClass = | 474 growableListClass = |
| 475 loadClass(growableListName, fletchSystemLibrary)?.element; | 475 loadClass(growableListName, dartinoSystemLibrary)?.element; |
| 476 fletchNoSuchMethodErrorClass = | 476 dartinoNoSuchMethodErrorClass = |
| 477 loadClass(fletchNoSuchMethodErrorName, | 477 loadClass(dartinoNoSuchMethodErrorName, |
| 478 fletchSystemLibrary, | 478 dartinoSystemLibrary, |
| 479 builtin: true)?.element; | 479 builtin: true)?.element; |
| 480 | 480 |
| 481 // This class is optional. | 481 // This class is optional. |
| 482 coroutineClass = fletchSystemLibrary.implementation.find("Coroutine"); | 482 coroutineClass = dartinoSystemLibrary.implementation.find("Coroutine"); |
| 483 if (coroutineClass != null) { | 483 if (coroutineClass != null) { |
| 484 coroutineClass.ensureResolved(compiler.resolution); | 484 coroutineClass.ensureResolved(compiler.resolution); |
| 485 } | 485 } |
| 486 } | 486 } |
| 487 | 487 |
| 488 void onElementResolved(Element element, TreeElements elements) { | 488 void onElementResolved(Element element, TreeElements elements) { |
| 489 if (alwaysEnqueue.contains(element)) { | 489 if (alwaysEnqueue.contains(element)) { |
| 490 var registry = new FletchRegistry(compiler); | 490 var registry = new DartinoRegistry(compiler); |
| 491 if (element.isStatic || element.isTopLevel) { | 491 if (element.isStatic || element.isTopLevel) { |
| 492 registry.registerStaticUse(new StaticUse.foreignUse(element)); | 492 registry.registerStaticUse(new StaticUse.foreignUse(element)); |
| 493 } else { | 493 } else { |
| 494 registry.registerDynamicUse(new Selector.fromElement(element)); | 494 registry.registerDynamicUse(new Selector.fromElement(element)); |
| 495 } | 495 } |
| 496 } | 496 } |
| 497 } | 497 } |
| 498 | 498 |
| 499 ClassElement get intImplementation => smiClass; | 499 ClassElement get intImplementation => smiClass; |
| 500 | 500 |
| 501 /// Class of annotations to mark patches in patch files. | 501 /// Class of annotations to mark patches in patch files. |
| 502 /// | 502 /// |
| 503 /// The patch parser (pkg/compiler/lib/src/patch_parser.dart). The patch | 503 /// The patch parser (pkg/compiler/lib/src/patch_parser.dart). The patch |
| 504 /// parser looks for an annotation on the form "@patch", where "patch" is | 504 /// parser looks for an annotation on the form "@patch", where "patch" is |
| 505 /// compile-time constant instance of [patchAnnotationClass]. | 505 /// compile-time constant instance of [patchAnnotationClass]. |
| 506 ClassElement get patchAnnotationClass { | 506 ClassElement get patchAnnotationClass { |
| 507 // TODO(ahe): Introduce a proper constant class to identify constants. For | 507 // TODO(ahe): Introduce a proper constant class to identify constants. For |
| 508 // now, we simply put "const patch = "patch";" in fletch._system. | 508 // now, we simply put "const patch = "patch";" in dartino._system. |
| 509 return super.stringImplementation; | 509 return super.stringImplementation; |
| 510 } | 510 } |
| 511 | 511 |
| 512 FletchClassBuilder createClosureClass( | 512 DartinoClassBuilder createClosureClass( |
| 513 FunctionElement closure, | 513 FunctionElement closure, |
| 514 ClosureEnvironment closureEnvironment) { | 514 ClosureEnvironment closureEnvironment) { |
| 515 return closureClasses.putIfAbsent(closure, () { | 515 return closureClasses.putIfAbsent(closure, () { |
| 516 ClosureInfo info = closureEnvironment.closures[closure]; | 516 ClosureInfo info = closureEnvironment.closures[closure]; |
| 517 int fields = info.free.length; | 517 int fields = info.free.length; |
| 518 if (info.isThisFree) fields++; | 518 if (info.isThisFree) fields++; |
| 519 return createCallableStubClass( | 519 return createCallableStubClass( |
| 520 fields, | 520 fields, |
| 521 closure.functionSignature.parameterCount, | 521 closure.functionSignature.parameterCount, |
| 522 compiledClosureClass); | 522 compiledClosureClass); |
| 523 }); | 523 }); |
| 524 } | 524 } |
| 525 | 525 |
| 526 /** | 526 /** |
| 527 * Create a tearoff class for function [function]. | 527 * Create a tearoff class for function [function]. |
| 528 * | 528 * |
| 529 * The class will have one method named 'call', accepting the same arguments | 529 * The class will have one method named 'call', accepting the same arguments |
| 530 * as [function]. The method will load the arguments received and statically | 530 * as [function]. The method will load the arguments received and statically |
| 531 * call [function] (essential a tail-call). | 531 * call [function] (essential a tail-call). |
| 532 * | 532 * |
| 533 * If [function] is an instance member, the class will have one field, the | 533 * If [function] is an instance member, the class will have one field, the |
| 534 * instance. | 534 * instance. |
| 535 */ | 535 */ |
| 536 FletchClassBuilder createTearoffClass(FletchFunctionBase function) { | 536 DartinoClassBuilder createTearoffClass(DartinoFunctionBase function) { |
| 537 FletchClassBuilder tearoffClass = | 537 DartinoClassBuilder tearoffClass = |
| 538 systemBuilder.getTearoffClassBuilder(function, compiledClosureClass); | 538 systemBuilder.getTearoffClassBuilder(function, compiledClosureClass); |
| 539 if (tearoffClass != null) return tearoffClass; | 539 if (tearoffClass != null) return tearoffClass; |
| 540 FunctionSignature signature = function.signature; | 540 FunctionSignature signature = function.signature; |
| 541 bool hasThis = function.isInstanceMember; | 541 bool hasThis = function.isInstanceMember; |
| 542 tearoffClass = createCallableStubClass( | 542 tearoffClass = createCallableStubClass( |
| 543 hasThis ? 1 : 0, | 543 hasThis ? 1 : 0, |
| 544 signature.parameterCount, | 544 signature.parameterCount, |
| 545 compiledClosureClass); | 545 compiledClosureClass); |
| 546 | 546 |
| 547 FletchFunctionBuilder functionBuilder = | 547 DartinoFunctionBuilder functionBuilder = |
| 548 systemBuilder.newTearOff(function, tearoffClass.classId); | 548 systemBuilder.newTearOff(function, tearoffClass.classId); |
| 549 | 549 |
| 550 BytecodeAssembler assembler = functionBuilder.assembler; | 550 BytecodeAssembler assembler = functionBuilder.assembler; |
| 551 int argumentCount = signature.parameterCount; | 551 int argumentCount = signature.parameterCount; |
| 552 if (hasThis) { | 552 if (hasThis) { |
| 553 argumentCount++; | 553 argumentCount++; |
| 554 // If the tearoff has a 'this' value, load it. It's the only field | 554 // If the tearoff has a 'this' value, load it. It's the only field |
| 555 // in the tearoff class. | 555 // in the tearoff class. |
| 556 assembler | 556 assembler |
| 557 ..loadParameter(0) | 557 ..loadParameter(0) |
| 558 ..loadField(0); | 558 ..loadField(0); |
| 559 } | 559 } |
| 560 for (int i = 0; i < signature.parameterCount; i++) { | 560 for (int i = 0; i < signature.parameterCount; i++) { |
| 561 // The closure-class is at parameter index 0, so argument i is at | 561 // The closure-class is at parameter index 0, so argument i is at |
| 562 // i + 1. | 562 // i + 1. |
| 563 assembler.loadParameter(i + 1); | 563 assembler.loadParameter(i + 1); |
| 564 } | 564 } |
| 565 int constId = functionBuilder.allocateConstantFromFunction( | 565 int constId = functionBuilder.allocateConstantFromFunction( |
| 566 function.functionId); | 566 function.functionId); |
| 567 // TODO(ajohnsen): Create a tail-call bytecode, so we don't have to | 567 // TODO(ajohnsen): Create a tail-call bytecode, so we don't have to |
| 568 // load all the arguments. | 568 // load all the arguments. |
| 569 assembler | 569 assembler |
| 570 ..invokeStatic(constId, argumentCount) | 570 ..invokeStatic(constId, argumentCount) |
| 571 ..ret() | 571 ..ret() |
| 572 ..methodEnd(); | 572 ..methodEnd(); |
| 573 | 573 |
| 574 String symbol = context.getCallSymbol(signature); | 574 String symbol = context.getCallSymbol(signature); |
| 575 int id = context.getSymbolId(symbol); | 575 int id = context.getSymbolId(symbol); |
| 576 int fletchSelector = FletchSelector.encodeMethod( | 576 int dartinoSelector = DartinoSelector.encodeMethod( |
| 577 id, | 577 id, |
| 578 signature.parameterCount); | 578 signature.parameterCount); |
| 579 tearoffClass.addToMethodTable(fletchSelector, functionBuilder); | 579 tearoffClass.addToMethodTable(dartinoSelector, functionBuilder); |
| 580 | 580 |
| 581 if (!function.isInstanceMember) return tearoffClass; | 581 if (!function.isInstanceMember) return tearoffClass; |
| 582 | 582 |
| 583 ClassElement classElement = | 583 ClassElement classElement = |
| 584 systemBuilder.lookupClassBuilder(function.memberOf).element; | 584 systemBuilder.lookupClassBuilder(function.memberOf).element; |
| 585 if (classElement == null) return tearoffClass; | 585 if (classElement == null) return tearoffClass; |
| 586 | 586 |
| 587 // Create == function that tests for equality. | 587 // Create == function that tests for equality. |
| 588 int isSelector = context.toFletchTearoffIsSelector( | 588 int isSelector = context.toDartinoTearoffIsSelector( |
| 589 function.name, | 589 function.name, |
| 590 classElement); | 590 classElement); |
| 591 tearoffClass.addIsSelector(isSelector); | 591 tearoffClass.addIsSelector(isSelector); |
| 592 | 592 |
| 593 FletchFunctionBuilder equal = systemBuilder.newFunctionBuilder( | 593 DartinoFunctionBuilder equal = systemBuilder.newFunctionBuilder( |
| 594 FletchFunctionKind.NORMAL, | 594 DartinoFunctionKind.NORMAL, |
| 595 2); | 595 2); |
| 596 | 596 |
| 597 BytecodeLabel isFalse = new BytecodeLabel(); | 597 BytecodeLabel isFalse = new BytecodeLabel(); |
| 598 equal.assembler | 598 equal.assembler |
| 599 // First test for class. This ensures it's the exact function that | 599 // First test for class. This ensures it's the exact function that |
| 600 // we expect. | 600 // we expect. |
| 601 ..loadParameter(1) | 601 ..loadParameter(1) |
| 602 ..invokeTest(isSelector, 0) | 602 ..invokeTest(isSelector, 0) |
| 603 ..branchIfFalse(isFalse) | 603 ..branchIfFalse(isFalse) |
| 604 // Then test that the receiver is identical. | 604 // Then test that the receiver is identical. |
| 605 ..loadParameter(0) | 605 ..loadParameter(0) |
| 606 ..loadField(0) | 606 ..loadField(0) |
| 607 ..loadParameter(1) | 607 ..loadParameter(1) |
| 608 ..loadField(0) | 608 ..loadField(0) |
| 609 ..identicalNonNumeric() | 609 ..identicalNonNumeric() |
| 610 ..branchIfFalse(isFalse) | 610 ..branchIfFalse(isFalse) |
| 611 ..loadLiteralTrue() | 611 ..loadLiteralTrue() |
| 612 ..ret() | 612 ..ret() |
| 613 ..bind(isFalse) | 613 ..bind(isFalse) |
| 614 ..loadLiteralFalse() | 614 ..loadLiteralFalse() |
| 615 ..ret() | 615 ..ret() |
| 616 ..methodEnd(); | 616 ..methodEnd(); |
| 617 | 617 |
| 618 id = context.getSymbolId("=="); | 618 id = context.getSymbolId("=="); |
| 619 int equalsSelector = FletchSelector.encodeMethod(id, 1); | 619 int equalsSelector = DartinoSelector.encodeMethod(id, 1); |
| 620 tearoffClass.addToMethodTable(equalsSelector, equal); | 620 tearoffClass.addToMethodTable(equalsSelector, equal); |
| 621 | 621 |
| 622 // Create hashCode getter. We simply add the object hashCode and the | 622 // Create hashCode getter. We simply add the object hashCode and the |
| 623 // method id of the tearoff'ed function. | 623 // method id of the tearoff'ed function. |
| 624 FletchFunctionBuilder hashCode = systemBuilder.newFunctionBuilder( | 624 DartinoFunctionBuilder hashCode = systemBuilder.newFunctionBuilder( |
| 625 FletchFunctionKind.ACCESSOR, | 625 DartinoFunctionKind.ACCESSOR, |
| 626 1); | 626 1); |
| 627 | 627 |
| 628 int hashCodeSelector = FletchSelector.encodeGetter( | 628 int hashCodeSelector = DartinoSelector.encodeGetter( |
| 629 context.getSymbolId("hashCode")); | 629 context.getSymbolId("hashCode")); |
| 630 | 630 |
| 631 // TODO(ajohnsen): Use plus, we plus is always enqueued. Consider using | 631 // TODO(ajohnsen): Use plus, we plus is always enqueued. Consider using |
| 632 // xor when we have a way to enqueue it from here. | 632 // xor when we have a way to enqueue it from here. |
| 633 int plusSelector = FletchSelector.encodeMethod( | 633 int plusSelector = DartinoSelector.encodeMethod( |
| 634 context.getSymbolId("+"), 1); | 634 context.getSymbolId("+"), 1); |
| 635 | 635 |
| 636 hashCode.assembler | 636 hashCode.assembler |
| 637 ..loadParameter(0) | 637 ..loadParameter(0) |
| 638 ..loadField(0) | 638 ..loadField(0) |
| 639 ..invokeMethod(hashCodeSelector, 0) | 639 ..invokeMethod(hashCodeSelector, 0) |
| 640 ..loadLiteral(function.functionId) | 640 ..loadLiteral(function.functionId) |
| 641 ..invokeMethod(plusSelector, 1) | 641 ..invokeMethod(plusSelector, 1) |
| 642 ..ret() | 642 ..ret() |
| 643 ..methodEnd(); | 643 ..methodEnd(); |
| 644 | 644 |
| 645 tearoffClass.addToMethodTable(hashCodeSelector, hashCode); | 645 tearoffClass.addToMethodTable(hashCodeSelector, hashCode); |
| 646 | 646 |
| 647 return tearoffClass; | 647 return tearoffClass; |
| 648 } | 648 } |
| 649 | 649 |
| 650 FletchFunctionBase getFunctionForElement(FunctionElement element) { | 650 DartinoFunctionBase getFunctionForElement(FunctionElement element) { |
| 651 assert(element.memberContext == element); | 651 assert(element.memberContext == element); |
| 652 | 652 |
| 653 FletchFunctionBase function = | 653 DartinoFunctionBase function = |
| 654 systemBuilder.lookupFunctionByElement(element); | 654 systemBuilder.lookupFunctionByElement(element); |
| 655 if (function != null) return function; | 655 if (function != null) return function; |
| 656 | 656 |
| 657 return createFletchFunctionBuilder(element); | 657 return createDartinoFunctionBuilder(element); |
| 658 } | 658 } |
| 659 | 659 |
| 660 /// Get the constructor initializer function for [constructor]. The function | 660 /// Get the constructor initializer function for [constructor]. The function |
| 661 /// will be created the first time it's called for [constructor]. | 661 /// will be created the first time it's called for [constructor]. |
| 662 /// | 662 /// |
| 663 /// See [compilePendingConstructorInitializers] for an overview of | 663 /// See [compilePendingConstructorInitializers] for an overview of |
| 664 /// constructor intializers and constructor bodies. | 664 /// constructor intializers and constructor bodies. |
| 665 FletchFunctionBase getConstructorInitializerFunction( | 665 DartinoFunctionBase getConstructorInitializerFunction( |
| 666 ConstructorElement constructor) { | 666 ConstructorElement constructor) { |
| 667 assert(constructor.isDeclaration); | 667 assert(constructor.isDeclaration); |
| 668 constructor = constructor.implementation; | 668 constructor = constructor.implementation; |
| 669 FletchFunctionBase base = | 669 DartinoFunctionBase base = |
| 670 systemBuilder.lookupConstructorInitializerByElement(constructor); | 670 systemBuilder.lookupConstructorInitializerByElement(constructor); |
| 671 if (base != null) return base; | 671 if (base != null) return base; |
| 672 | 672 |
| 673 FletchFunctionBuilder builder = systemBuilder.newConstructorInitializer( | 673 DartinoFunctionBuilder builder = systemBuilder.newConstructorInitializer( |
| 674 constructor); | 674 constructor); |
| 675 pendingConstructorInitializers.addFirst(builder); | 675 pendingConstructorInitializers.addFirst(builder); |
| 676 | 676 |
| 677 return builder; | 677 return builder; |
| 678 } | 678 } |
| 679 | 679 |
| 680 FletchFunctionBuilder createFletchFunctionBuilder(FunctionElement function) { | 680 DartinoFunctionBuilder createDartinoFunctionBuilder(FunctionElement function)
{ |
| 681 assert(function.memberContext == function); | 681 assert(function.memberContext == function); |
| 682 | 682 |
| 683 FletchClassBuilder holderClass; | 683 DartinoClassBuilder holderClass; |
| 684 if (function.isInstanceMember || function.isGenerativeConstructor) { | 684 if (function.isInstanceMember || function.isGenerativeConstructor) { |
| 685 ClassElement enclosingClass = function.enclosingClass.declaration; | 685 ClassElement enclosingClass = function.enclosingClass.declaration; |
| 686 holderClass = registerClassElement(enclosingClass); | 686 holderClass = registerClassElement(enclosingClass); |
| 687 } | 687 } |
| 688 return internalCreateFletchFunctionBuilder( | 688 return internalCreateDartinoFunctionBuilder( |
| 689 function, | 689 function, |
| 690 function.name, | 690 function.name, |
| 691 holderClass); | 691 holderClass); |
| 692 } | 692 } |
| 693 | 693 |
| 694 FletchFunctionBuilder internalCreateFletchFunctionBuilder( | 694 DartinoFunctionBuilder internalCreateDartinoFunctionBuilder( |
| 695 FunctionElement function, | 695 FunctionElement function, |
| 696 String name, | 696 String name, |
| 697 FletchClassBuilder holderClass) { | 697 DartinoClassBuilder holderClass) { |
| 698 FletchFunctionBuilder functionBuilder = | 698 DartinoFunctionBuilder functionBuilder = |
| 699 systemBuilder.lookupFunctionBuilderByElement(function.declaration); | 699 systemBuilder.lookupFunctionBuilderByElement(function.declaration); |
| 700 if (functionBuilder != null) return functionBuilder; | 700 if (functionBuilder != null) return functionBuilder; |
| 701 | 701 |
| 702 FunctionTypedElement implementation = function.implementation; | 702 FunctionTypedElement implementation = function.implementation; |
| 703 int memberOf = holderClass != null ? holderClass.classId : null; | 703 int memberOf = holderClass != null ? holderClass.classId : null; |
| 704 return systemBuilder.newFunctionBuilderWithSignature( | 704 return systemBuilder.newFunctionBuilderWithSignature( |
| 705 name, | 705 name, |
| 706 function, | 706 function, |
| 707 // Parameter initializers are expressed in the potential | 707 // Parameter initializers are expressed in the potential |
| 708 // implementation. | 708 // implementation. |
| 709 implementation.functionSignature, | 709 implementation.functionSignature, |
| 710 memberOf, | 710 memberOf, |
| 711 kind: function.isAccessor | 711 kind: function.isAccessor |
| 712 ? FletchFunctionKind.ACCESSOR | 712 ? DartinoFunctionKind.ACCESSOR |
| 713 : FletchFunctionKind.NORMAL, | 713 : DartinoFunctionKind.NORMAL, |
| 714 mapByElement: function.declaration); | 714 mapByElement: function.declaration); |
| 715 } | 715 } |
| 716 | 716 |
| 717 ClassDebugInfo createClassDebugInfo(FletchClass klass) { | 717 ClassDebugInfo createClassDebugInfo(DartinoClass klass) { |
| 718 return new ClassDebugInfo(klass); | 718 return new ClassDebugInfo(klass); |
| 719 } | 719 } |
| 720 | 720 |
| 721 DebugInfo createDebugInfo( | 721 DebugInfo createDebugInfo( |
| 722 FletchFunction function, | 722 DartinoFunction function, |
| 723 FletchSystem currentSystem) { | 723 DartinoSystem currentSystem) { |
| 724 DebugInfo debugInfo = new DebugInfo(function); | 724 DebugInfo debugInfo = new DebugInfo(function); |
| 725 AstElement element = function.element; | 725 AstElement element = function.element; |
| 726 if (element == null) return debugInfo; | 726 if (element == null) return debugInfo; |
| 727 List<Bytecode> expectedBytecodes = function.bytecodes; | 727 List<Bytecode> expectedBytecodes = function.bytecodes; |
| 728 element = element.implementation; | 728 element = element.implementation; |
| 729 TreeElements elements = element.resolvedAst.elements; | 729 TreeElements elements = element.resolvedAst.elements; |
| 730 ClosureEnvironment closureEnvironment = createClosureEnvironment( | 730 ClosureEnvironment closureEnvironment = createClosureEnvironment( |
| 731 element, | 731 element, |
| 732 elements); | 732 elements); |
| 733 CodegenVisitor codegen; | 733 CodegenVisitor codegen; |
| 734 FletchFunctionBuilder builder = | 734 DartinoFunctionBuilder builder = |
| 735 new FletchFunctionBuilder.fromFletchFunction(function); | 735 new DartinoFunctionBuilder.fromDartinoFunction(function); |
| 736 if (function.isLazyFieldInitializer) { | 736 if (function.isLazyFieldInitializer) { |
| 737 codegen = new DebugInfoLazyFieldInitializerCodegen( | 737 codegen = new DebugInfoLazyFieldInitializerCodegen( |
| 738 debugInfo, | 738 debugInfo, |
| 739 builder, | 739 builder, |
| 740 context, | 740 context, |
| 741 elements, | 741 elements, |
| 742 closureEnvironment, | 742 closureEnvironment, |
| 743 element, | 743 element, |
| 744 compiler); | 744 compiler); |
| 745 } else if (function.isInitializerList) { | 745 } else if (function.isInitializerList) { |
| 746 ClassElement enclosingClass = element.enclosingClass; | 746 ClassElement enclosingClass = element.enclosingClass; |
| 747 // TODO(ajohnsen): Don't depend on the class builder. | 747 // TODO(ajohnsen): Don't depend on the class builder. |
| 748 FletchClassBuilder classBuilder = | 748 DartinoClassBuilder classBuilder = |
| 749 systemBuilder.lookupClassBuilderByElement(enclosingClass.declaration); | 749 systemBuilder.lookupClassBuilderByElement(enclosingClass.declaration); |
| 750 codegen = new DebugInfoConstructorCodegen( | 750 codegen = new DebugInfoConstructorCodegen( |
| 751 debugInfo, | 751 debugInfo, |
| 752 builder, | 752 builder, |
| 753 context, | 753 context, |
| 754 elements, | 754 elements, |
| 755 closureEnvironment, | 755 closureEnvironment, |
| 756 element, | 756 element, |
| 757 classBuilder, | 757 classBuilder, |
| 758 compiler); | 758 compiler); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 784 throw 'Debug info code different from running code.'; | 784 throw 'Debug info code different from running code.'; |
| 785 } | 785 } |
| 786 return debugInfo; | 786 return debugInfo; |
| 787 } | 787 } |
| 788 | 788 |
| 789 codegen(_) { | 789 codegen(_) { |
| 790 new UnsupportedError( | 790 new UnsupportedError( |
| 791 "Method [codegen] not supported, use [compileElement] instead"); | 791 "Method [codegen] not supported, use [compileElement] instead"); |
| 792 } | 792 } |
| 793 | 793 |
| 794 /// Invoked by [FletchEnqueuer] once per element that needs to be compiled. | 794 /// Invoked by [DartinoEnqueuer] once per element that needs to be compiled. |
| 795 /// | 795 /// |
| 796 /// This is used to generate the bytecodes for [declaration]. | 796 /// This is used to generate the bytecodes for [declaration]. |
| 797 void compileElement( | 797 void compileElement( |
| 798 AstElement declaration, | 798 AstElement declaration, |
| 799 TreeElements treeElements, | 799 TreeElements treeElements, |
| 800 FletchRegistry registry) { | 800 DartinoRegistry registry) { |
| 801 AstElement element = declaration.implementation; | 801 AstElement element = declaration.implementation; |
| 802 compiler.reporter.withCurrentElement(element, () { | 802 compiler.reporter.withCurrentElement(element, () { |
| 803 assert(declaration.isDeclaration); | 803 assert(declaration.isDeclaration); |
| 804 context.compiler.reportVerboseInfo(element, 'Compiling $element'); | 804 context.compiler.reportVerboseInfo(element, 'Compiling $element'); |
| 805 if (element.isFunction || | 805 if (element.isFunction || |
| 806 element.isGetter || | 806 element.isGetter || |
| 807 element.isSetter || | 807 element.isSetter || |
| 808 element.isGenerativeConstructor || | 808 element.isGenerativeConstructor || |
| 809 element.isFactoryConstructor) { | 809 element.isFactoryConstructor) { |
| 810 // For a generative constructor, this means compile the constructor | 810 // For a generative constructor, this means compile the constructor |
| 811 // body. See [compilePendingConstructorInitializers] for an overview of | 811 // body. See [compilePendingConstructorInitializers] for an overview of |
| 812 // how constructor initializers and constructor bodies are compiled. | 812 // how constructor initializers and constructor bodies are compiled. |
| 813 codegenFunction(element, treeElements, registry); | 813 codegenFunction(element, treeElements, registry); |
| 814 } else if (element.isField) { | 814 } else if (element.isField) { |
| 815 context.compiler.reportVerboseInfo( | 815 context.compiler.reportVerboseInfo( |
| 816 element, "Asked to compile a field, but don't know how"); | 816 element, "Asked to compile a field, but don't know how"); |
| 817 } else { | 817 } else { |
| 818 compiler.reporter.internalError( | 818 compiler.reporter.internalError( |
| 819 element, "Uninimplemented element kind: ${element.kind}"); | 819 element, "Uninimplemented element kind: ${element.kind}"); |
| 820 } | 820 } |
| 821 }); | 821 }); |
| 822 } | 822 } |
| 823 | 823 |
| 824 /// Invoked by [FletchEnqueuer] once per [selector] that may invoke | 824 /// Invoked by [DartinoEnqueuer] once per [selector] that may invoke |
| 825 /// [declaration]. | 825 /// [declaration]. |
| 826 /// | 826 /// |
| 827 /// This is used to generate stubs for [declaration]. | 827 /// This is used to generate stubs for [declaration]. |
| 828 void compileElementUsage( | 828 void compileElementUsage( |
| 829 AstElement declaration, | 829 AstElement declaration, |
| 830 Selector selector, | 830 Selector selector, |
| 831 TreeElements treeElements, | 831 TreeElements treeElements, |
| 832 FletchRegistry registry) { | 832 DartinoRegistry registry) { |
| 833 AstElement element = declaration.implementation; | 833 AstElement element = declaration.implementation; |
| 834 compiler.reporter.withCurrentElement(element, () { | 834 compiler.reporter.withCurrentElement(element, () { |
| 835 assert(declaration.isDeclaration); | 835 assert(declaration.isDeclaration); |
| 836 context.compiler.reportVerboseInfo(element, 'Compiling $element'); | 836 context.compiler.reportVerboseInfo(element, 'Compiling $element'); |
| 837 if (!element.isInstanceMember && !isLocalFunction(element)) { | 837 if (!element.isInstanceMember && !isLocalFunction(element)) { |
| 838 // No stub needed. Optional arguments are handled at call-site. | 838 // No stub needed. Optional arguments are handled at call-site. |
| 839 } else if (element.isFunction) { | 839 } else if (element.isFunction) { |
| 840 FletchFunctionBase function = | 840 DartinoFunctionBase function = |
| 841 systemBuilder.lookupFunctionByElement(element.declaration); | 841 systemBuilder.lookupFunctionByElement(element.declaration); |
| 842 CallStructure callStructure = selector.callStructure; | 842 CallStructure callStructure = selector.callStructure; |
| 843 FunctionSignature signature = function.signature; | 843 FunctionSignature signature = function.signature; |
| 844 if (selector.isGetter) { | 844 if (selector.isGetter) { |
| 845 if (shouldReportEnqueuingOfElement(compiler, element)) { | 845 if (shouldReportEnqueuingOfElement(compiler, element)) { |
| 846 context.compiler.reportVerboseInfo( | 846 context.compiler.reportVerboseInfo( |
| 847 element, 'Adding tear-off stub'); | 847 element, 'Adding tear-off stub'); |
| 848 } | 848 } |
| 849 createTearoffGetterForFunction( | 849 createTearoffGetterForFunction( |
| 850 function, isSpecialCallMethod: element.name == "call"); | 850 function, isSpecialCallMethod: element.name == "call"); |
| 851 } else if (selector.isCall && | 851 } else if (selector.isCall && |
| 852 callStructure.signatureApplies(signature) && | 852 callStructure.signatureApplies(signature) && |
| 853 !isExactParameterMatch(signature, callStructure)) { | 853 !isExactParameterMatch(signature, callStructure)) { |
| 854 if (shouldReportEnqueuingOfElement(compiler, element)) { | 854 if (shouldReportEnqueuingOfElement(compiler, element)) { |
| 855 context.compiler.reportVerboseInfo( | 855 context.compiler.reportVerboseInfo( |
| 856 element, 'Adding stub for $selector'); | 856 element, 'Adding stub for $selector'); |
| 857 } | 857 } |
| 858 createParameterStub(function, selector); | 858 createParameterStub(function, selector); |
| 859 } | 859 } |
| 860 } else if (element.isGetter || element.isSetter) { | 860 } else if (element.isGetter || element.isSetter) { |
| 861 // No stub needed. If a getter returns a closure, the VM's | 861 // No stub needed. If a getter returns a closure, the VM's |
| 862 // no-such-method handling will do the right thing. | 862 // no-such-method handling will do the right thing. |
| 863 } else { | 863 } else { |
| 864 context.compiler.reportVerboseInfo( | 864 context.compiler.reportVerboseInfo( |
| 865 element, "Asked to compile this, but don't know how"); | 865 element, "Asked to compile this, but don't know how"); |
| 866 } | 866 } |
| 867 }); | 867 }); |
| 868 } | 868 } |
| 869 | 869 |
| 870 /// Invoked by [FletchEnqueuer] once per `call` [selector] that may invoke | 870 /// Invoked by [DartinoEnqueuer] once per `call` [selector] that may invoke |
| 871 /// [declaration] as an implicit closure (for example, a tear-off). | 871 /// [declaration] as an implicit closure (for example, a tear-off). |
| 872 /// | 872 /// |
| 873 /// This is used to generate parameter stubs for the closures. | 873 /// This is used to generate parameter stubs for the closures. |
| 874 void compileClosurizationUsage( | 874 void compileClosurizationUsage( |
| 875 AstElement declaration, | 875 AstElement declaration, |
| 876 Selector selector, | 876 Selector selector, |
| 877 TreeElements treeElements, | 877 TreeElements treeElements, |
| 878 FletchRegistry registry, | 878 DartinoRegistry registry, |
| 879 ClosureKind kind) { | 879 ClosureKind kind) { |
| 880 AstElement element = declaration.implementation; | 880 AstElement element = declaration.implementation; |
| 881 compiler.reporter.withCurrentElement(element, () { | 881 compiler.reporter.withCurrentElement(element, () { |
| 882 assert(declaration.isDeclaration); | 882 assert(declaration.isDeclaration); |
| 883 if (shouldReportEnqueuingOfElement(compiler, element)) { | 883 if (shouldReportEnqueuingOfElement(compiler, element)) { |
| 884 context.compiler.reportVerboseInfo( | 884 context.compiler.reportVerboseInfo( |
| 885 element, 'Need tear-off parameter stub $selector'); | 885 element, 'Need tear-off parameter stub $selector'); |
| 886 } | 886 } |
| 887 FletchFunctionBase function = | 887 DartinoFunctionBase function = |
| 888 systemBuilder.lookupFunctionByElement(element.declaration); | 888 systemBuilder.lookupFunctionByElement(element.declaration); |
| 889 if (function == null) { | 889 if (function == null) { |
| 890 compiler.reporter.internalError( | 890 compiler.reporter.internalError( |
| 891 element, "Has no fletch function, but used as tear-off"); | 891 element, "Has no dartino function, but used as tear-off"); |
| 892 } | 892 } |
| 893 if (selector.isGetter) { | 893 if (selector.isGetter) { |
| 894 // This is a special tear-off getter. | 894 // This is a special tear-off getter. |
| 895 | 895 |
| 896 // TODO(ahe): This code should probably use [kind] to detect the | 896 // TODO(ahe): This code should probably use [kind] to detect the |
| 897 // various cases instead of [isLocalFunction] and looking at names. | 897 // various cases instead of [isLocalFunction] and looking at names. |
| 898 | 898 |
| 899 assert(selector.memberName == Names.CALL_NAME); | 899 assert(selector.memberName == Names.CALL_NAME); |
| 900 if (isLocalFunction(element) || | 900 if (isLocalFunction(element) || |
| 901 memberName(element) == Names.CALL_NAME) { | 901 memberName(element) == Names.CALL_NAME) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 | 944 |
| 945 if (!isExactParameterMatch(function.signature, selector.callStructure)) { | 945 if (!isExactParameterMatch(function.signature, selector.callStructure)) { |
| 946 createParameterStub(function, selector); | 946 createParameterStub(function, selector); |
| 947 } | 947 } |
| 948 }); | 948 }); |
| 949 } | 949 } |
| 950 | 950 |
| 951 void codegenFunction( | 951 void codegenFunction( |
| 952 FunctionElement function, | 952 FunctionElement function, |
| 953 TreeElements elements, | 953 TreeElements elements, |
| 954 FletchRegistry registry) { | 954 DartinoRegistry registry) { |
| 955 registry.registerStaticUse(new StaticUse.foreignUse(fletchSystemEntry)); | 955 registry.registerStaticUse(new StaticUse.foreignUse(dartinoSystemEntry)); |
| 956 | 956 |
| 957 ClosureEnvironment closureEnvironment = createClosureEnvironment( | 957 ClosureEnvironment closureEnvironment = createClosureEnvironment( |
| 958 function, | 958 function, |
| 959 elements); | 959 elements); |
| 960 | 960 |
| 961 FletchFunctionBuilder functionBuilder; | 961 DartinoFunctionBuilder functionBuilder; |
| 962 | 962 |
| 963 if (function.memberContext != function) { | 963 if (function.memberContext != function) { |
| 964 functionBuilder = internalCreateFletchFunctionBuilder( | 964 functionBuilder = internalCreateDartinoFunctionBuilder( |
| 965 function, | 965 function, |
| 966 Identifiers.call, | 966 Identifiers.call, |
| 967 createClosureClass(function, closureEnvironment)); | 967 createClosureClass(function, closureEnvironment)); |
| 968 } else { | 968 } else { |
| 969 functionBuilder = createFletchFunctionBuilder(function); | 969 functionBuilder = createDartinoFunctionBuilder(function); |
| 970 } | 970 } |
| 971 | 971 |
| 972 FunctionCodegen codegen = new FunctionCodegen( | 972 FunctionCodegen codegen = new FunctionCodegen( |
| 973 functionBuilder, | 973 functionBuilder, |
| 974 context, | 974 context, |
| 975 elements, | 975 elements, |
| 976 registry, | 976 registry, |
| 977 closureEnvironment, | 977 closureEnvironment, |
| 978 function); | 978 function); |
| 979 | 979 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 991 // them into the method table. | 991 // them into the method table. |
| 992 String symbol = context.getSymbolForFunction( | 992 String symbol = context.getSymbolForFunction( |
| 993 functionBuilder.name, | 993 functionBuilder.name, |
| 994 function.functionSignature, | 994 function.functionSignature, |
| 995 function.library); | 995 function.library); |
| 996 int id = context.getSymbolId(symbol); | 996 int id = context.getSymbolId(symbol); |
| 997 int arity = function.functionSignature.parameterCount; | 997 int arity = function.functionSignature.parameterCount; |
| 998 SelectorKind kind = SelectorKind.Method; | 998 SelectorKind kind = SelectorKind.Method; |
| 999 if (function.isGetter) kind = SelectorKind.Getter; | 999 if (function.isGetter) kind = SelectorKind.Getter; |
| 1000 if (function.isSetter) kind = SelectorKind.Setter; | 1000 if (function.isSetter) kind = SelectorKind.Setter; |
| 1001 int fletchSelector = FletchSelector.encode(id, kind, arity); | 1001 int dartinoSelector = DartinoSelector.encode(id, kind, arity); |
| 1002 FletchClassBuilder classBuilder = | 1002 DartinoClassBuilder classBuilder = |
| 1003 systemBuilder.lookupClassBuilder(functionBuilder.memberOf); | 1003 systemBuilder.lookupClassBuilder(functionBuilder.memberOf); |
| 1004 classBuilder.addToMethodTable(fletchSelector, functionBuilder); | 1004 classBuilder.addToMethodTable(dartinoSelector, functionBuilder); |
| 1005 // Inject method into all mixin usages. | 1005 // Inject method into all mixin usages. |
| 1006 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { | 1006 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { |
| 1007 FletchClassBuilder compiledUsage = registerClassElement(usage); | 1007 DartinoClassBuilder compiledUsage = registerClassElement(usage); |
| 1008 compiledUsage.addToMethodTable(fletchSelector, functionBuilder); | 1008 compiledUsage.addToMethodTable(dartinoSelector, functionBuilder); |
| 1009 }); | 1009 }); |
| 1010 } | 1010 } |
| 1011 | 1011 |
| 1012 if (compiler.verbose) { | 1012 if (compiler.verbose) { |
| 1013 context.compiler.reportVerboseInfo( | 1013 context.compiler.reportVerboseInfo( |
| 1014 function, functionBuilder.verboseToString()); | 1014 function, functionBuilder.verboseToString()); |
| 1015 } | 1015 } |
| 1016 } | 1016 } |
| 1017 | 1017 |
| 1018 List<ClassElement> getMixinApplicationsOfClass(FletchClassBuilder builder) { | 1018 List<ClassElement> getMixinApplicationsOfClass(DartinoClassBuilder builder) { |
| 1019 ClassElement element = builder.element; | 1019 ClassElement element = builder.element; |
| 1020 if (element == null) return []; | 1020 if (element == null) return []; |
| 1021 List<ClassElement> mixinUsage = | 1021 List<ClassElement> mixinUsage = |
| 1022 compiler.world.mixinUsesOf(element).toList(); | 1022 compiler.world.mixinUsesOf(element).toList(); |
| 1023 for (int i = 0; i < mixinUsage.length; i++) { | 1023 for (int i = 0; i < mixinUsage.length; i++) { |
| 1024 ClassElement usage = mixinUsage[i]; | 1024 ClassElement usage = mixinUsage[i]; |
| 1025 // Recursively add mixin-usage of the current 'usage'. | 1025 // Recursively add mixin-usage of the current 'usage'. |
| 1026 assert(!compiler.world.mixinUsesOf(usage).any(mixinUsage.contains)); | 1026 assert(!compiler.world.mixinUsesOf(usage).any(mixinUsage.contains)); |
| 1027 mixinUsage.addAll(compiler.world.mixinUsesOf(usage)); | 1027 mixinUsage.addAll(compiler.world.mixinUsesOf(usage)); |
| 1028 } | 1028 } |
| 1029 return mixinUsage; | 1029 return mixinUsage; |
| 1030 } | 1030 } |
| 1031 | 1031 |
| 1032 void codegenNativeFunction( | 1032 void codegenNativeFunction( |
| 1033 FunctionElement function, | 1033 FunctionElement function, |
| 1034 FunctionCodegen codegen) { | 1034 FunctionCodegen codegen) { |
| 1035 String name = '.${function.name}'; | 1035 String name = '.${function.name}'; |
| 1036 | 1036 |
| 1037 ClassElement enclosingClass = function.enclosingClass; | 1037 ClassElement enclosingClass = function.enclosingClass; |
| 1038 if (enclosingClass != null) name = '${enclosingClass.name}$name'; | 1038 if (enclosingClass != null) name = '${enclosingClass.name}$name'; |
| 1039 | 1039 |
| 1040 FletchNativeDescriptor descriptor = context.nativeDescriptors[name]; | 1040 DartinoNativeDescriptor descriptor = context.nativeDescriptors[name]; |
| 1041 if (descriptor == null) { | 1041 if (descriptor == null) { |
| 1042 throw "Unsupported native function: $name"; | 1042 throw "Unsupported native function: $name"; |
| 1043 } | 1043 } |
| 1044 | 1044 |
| 1045 if (name == "Coroutine._coroutineNewStack") { | 1045 if (name == "Coroutine._coroutineNewStack") { |
| 1046 // The static native method `Coroutine._coroutineNewStack` will invoke | 1046 // The static native method `Coroutine._coroutineNewStack` will invoke |
| 1047 // the instance method `Coroutine._coroutineStart`. | 1047 // the instance method `Coroutine._coroutineStart`. |
| 1048 if (coroutineClass == null) { | 1048 if (coroutineClass == null) { |
| 1049 compiler.reporter.internalError( | 1049 compiler.reporter.internalError( |
| 1050 function, "required class [Coroutine] not found"); | 1050 function, "required class [Coroutine] not found"); |
| 1051 } | 1051 } |
| 1052 FunctionElement coroutineStart = | 1052 FunctionElement coroutineStart = |
| 1053 coroutineClass.lookupLocalMember("_coroutineStart"); | 1053 coroutineClass.lookupLocalMember("_coroutineStart"); |
| 1054 Selector selector = new Selector.fromElement(coroutineStart); | 1054 Selector selector = new Selector.fromElement(coroutineStart); |
| 1055 new FletchRegistry(compiler) | 1055 new DartinoRegistry(compiler) |
| 1056 ..registerDynamicUse(selector); | 1056 ..registerDynamicUse(selector); |
| 1057 } else if (name == "Process._spawn") { | 1057 } else if (name == "Process._spawn") { |
| 1058 // The native method `Process._spawn` will do a closure invoke with 0, 1, | 1058 // The native method `Process._spawn` will do a closure invoke with 0, 1, |
| 1059 // or 2 arguments. | 1059 // or 2 arguments. |
| 1060 new FletchRegistry(compiler) | 1060 new DartinoRegistry(compiler) |
| 1061 ..registerDynamicUse(new Selector.callClosure(0)) | 1061 ..registerDynamicUse(new Selector.callClosure(0)) |
| 1062 ..registerDynamicUse(new Selector.callClosure(1)) | 1062 ..registerDynamicUse(new Selector.callClosure(1)) |
| 1063 ..registerDynamicUse(new Selector.callClosure(2)); | 1063 ..registerDynamicUse(new Selector.callClosure(2)); |
| 1064 } | 1064 } |
| 1065 | 1065 |
| 1066 int arity = codegen.assembler.functionArity; | 1066 int arity = codegen.assembler.functionArity; |
| 1067 if (name == "Port.send" || | 1067 if (name == "Port.send" || |
| 1068 name == "Port._sendList" || | 1068 name == "Port._sendList" || |
| 1069 name == "Port._sendExit") { | 1069 name == "Port._sendExit") { |
| 1070 codegen.assembler.invokeNativeYield(arity, descriptor.index); | 1070 codegen.assembler.invokeNativeYield(arity, descriptor.index); |
| 1071 } else { | 1071 } else { |
| 1072 codegen.assembler.invokeNative(arity, descriptor.index); | 1072 codegen.assembler.invokeNative(arity, descriptor.index); |
| 1073 } | 1073 } |
| 1074 | 1074 |
| 1075 EmptyStatement empty = function.node.body.asEmptyStatement(); | 1075 EmptyStatement empty = function.node.body.asEmptyStatement(); |
| 1076 if (empty != null) { | 1076 if (empty != null) { |
| 1077 // A native method without a body. | 1077 // A native method without a body. |
| 1078 codegen.assembler | 1078 codegen.assembler |
| 1079 ..emitThrow() | 1079 ..emitThrow() |
| 1080 ..methodEnd(); | 1080 ..methodEnd(); |
| 1081 } else { | 1081 } else { |
| 1082 codegen.compile(); | 1082 codegen.compile(); |
| 1083 } | 1083 } |
| 1084 } | 1084 } |
| 1085 | 1085 |
| 1086 void codegenExternalFunction( | 1086 void codegenExternalFunction( |
| 1087 FunctionElement function, | 1087 FunctionElement function, |
| 1088 FunctionCodegen codegen) { | 1088 FunctionCodegen codegen) { |
| 1089 if (function == fletchExternalYield) { | 1089 if (function == dartinoExternalYield) { |
| 1090 codegenExternalYield(function, codegen); | 1090 codegenExternalYield(function, codegen); |
| 1091 } else if (function == context.compiler.identicalFunction.implementation) { | 1091 } else if (function == context.compiler.identicalFunction.implementation) { |
| 1092 codegenIdentical(function, codegen); | 1092 codegenIdentical(function, codegen); |
| 1093 } else if (function == fletchExternalInvokeMain) { | 1093 } else if (function == dartinoExternalInvokeMain) { |
| 1094 codegenExternalInvokeMain(function, codegen); | 1094 codegenExternalInvokeMain(function, codegen); |
| 1095 } else if (function.name == noSuchMethodTrampolineName && | 1095 } else if (function.name == noSuchMethodTrampolineName && |
| 1096 function.library == compiler.coreLibrary) { | 1096 function.library == compiler.coreLibrary) { |
| 1097 codegenExternalNoSuchMethodTrampoline(function, codegen); | 1097 codegenExternalNoSuchMethodTrampoline(function, codegen); |
| 1098 } else { | 1098 } else { |
| 1099 DiagnosticMessage message = context.compiler.reporter | 1099 DiagnosticMessage message = context.compiler.reporter |
| 1100 .createMessage(function.node, | 1100 .createMessage(function.node, |
| 1101 MessageKind.GENERIC, | 1101 MessageKind.GENERIC, |
| 1102 {'text': | 1102 {'text': |
| 1103 'External function "${function.name}" is not supported'}); | 1103 'External function "${function.name}" is not supported'}); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1140 } | 1140 } |
| 1141 | 1141 |
| 1142 void codegenExternalNoSuchMethodTrampoline( | 1142 void codegenExternalNoSuchMethodTrampoline( |
| 1143 FunctionElement function, | 1143 FunctionElement function, |
| 1144 FunctionCodegen codegen) { | 1144 FunctionCodegen codegen) { |
| 1145 // NOTE: The number of arguments to the [noSuchMethodName] function must be | 1145 // NOTE: The number of arguments to the [noSuchMethodName] function must be |
| 1146 // kept in sync with: | 1146 // kept in sync with: |
| 1147 // src/vm/interpreter.cc:HandleEnterNoSuchMethod | 1147 // src/vm/interpreter.cc:HandleEnterNoSuchMethod |
| 1148 int id = context.getSymbolId( | 1148 int id = context.getSymbolId( |
| 1149 context.mangleName(new Name(noSuchMethodName, compiler.coreLibrary))); | 1149 context.mangleName(new Name(noSuchMethodName, compiler.coreLibrary))); |
| 1150 int fletchSelector = FletchSelector.encodeMethod(id, 3); | 1150 int dartinoSelector = DartinoSelector.encodeMethod(id, 3); |
| 1151 BytecodeLabel skipGetter = new BytecodeLabel(); | 1151 BytecodeLabel skipGetter = new BytecodeLabel(); |
| 1152 codegen.assembler | 1152 codegen.assembler |
| 1153 ..enterNoSuchMethod(skipGetter) | 1153 ..enterNoSuchMethod(skipGetter) |
| 1154 // First invoke the getter. | 1154 // First invoke the getter. |
| 1155 ..invokeSelector(2) | 1155 ..invokeSelector(2) |
| 1156 // Then invoke 'call', with the receiver being the result of the | 1156 // Then invoke 'call', with the receiver being the result of the |
| 1157 // previous invokeSelector. | 1157 // previous invokeSelector. |
| 1158 ..invokeSelector(1) | 1158 ..invokeSelector(1) |
| 1159 ..exitNoSuchMethod() | 1159 ..exitNoSuchMethod() |
| 1160 ..bind(skipGetter) | 1160 ..bind(skipGetter) |
| 1161 ..invokeMethod(fletchSelector, 1) | 1161 ..invokeMethod(dartinoSelector, 1) |
| 1162 ..exitNoSuchMethod() | 1162 ..exitNoSuchMethod() |
| 1163 ..methodEnd(); | 1163 ..methodEnd(); |
| 1164 } | 1164 } |
| 1165 | 1165 |
| 1166 bool isNative(Element element) { | 1166 bool isNative(Element element) { |
| 1167 if (element is FunctionElement) { | 1167 if (element is FunctionElement) { |
| 1168 for (var metadata in element.metadata) { | 1168 for (var metadata in element.metadata) { |
| 1169 // TODO(ahe): This code should ensure that @native resolves to precisely | 1169 // TODO(ahe): This code should ensure that @native resolves to precisely |
| 1170 // the native variable in dart:fletch._system. | 1170 // the native variable in dart:dartino._system. |
| 1171 if (metadata.constant == null) continue; | 1171 if (metadata.constant == null) continue; |
| 1172 ConstantValue value = context.getConstantValue(metadata.constant); | 1172 ConstantValue value = context.getConstantValue(metadata.constant); |
| 1173 if (!value.isString) continue; | 1173 if (!value.isString) continue; |
| 1174 StringConstantValue stringValue = value; | 1174 StringConstantValue stringValue = value; |
| 1175 if (stringValue.toDartString().slowToString() != 'native') continue; | 1175 if (stringValue.toDartString().slowToString() != 'native') continue; |
| 1176 return true; | 1176 return true; |
| 1177 } | 1177 } |
| 1178 } | 1178 } |
| 1179 return false; | 1179 return false; |
| 1180 } | 1180 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1193 return closureEnvironments.putIfAbsent(member, () { | 1193 return closureEnvironments.putIfAbsent(member, () { |
| 1194 ClosureVisitor environment = new ClosureVisitor(member, elements); | 1194 ClosureVisitor environment = new ClosureVisitor(member, elements); |
| 1195 return environment.compute(); | 1195 return environment.compute(); |
| 1196 }); | 1196 }); |
| 1197 } | 1197 } |
| 1198 | 1198 |
| 1199 void markFunctionConstantAsUsed(FunctionConstantValue value) { | 1199 void markFunctionConstantAsUsed(FunctionConstantValue value) { |
| 1200 // TODO(ajohnsen): Use registry in CodegenVisitor to register the used | 1200 // TODO(ajohnsen): Use registry in CodegenVisitor to register the used |
| 1201 // constants. | 1201 // constants. |
| 1202 FunctionElement function = value.element; | 1202 FunctionElement function = value.element; |
| 1203 createTearoffClass(createFletchFunctionBuilder(function)); | 1203 createTearoffClass(createDartinoFunctionBuilder(function)); |
| 1204 // Be sure to actually enqueue the function for compilation. | 1204 // Be sure to actually enqueue the function for compilation. |
| 1205 FletchRegistry registry = new FletchRegistry(compiler); | 1205 DartinoRegistry registry = new DartinoRegistry(compiler); |
| 1206 registry.registerStaticUse(new StaticUse.foreignUse(function)); | 1206 registry.registerStaticUse(new StaticUse.foreignUse(function)); |
| 1207 } | 1207 } |
| 1208 | 1208 |
| 1209 FletchFunctionBase createParameterStub( | 1209 DartinoFunctionBase createParameterStub( |
| 1210 FletchFunctionBase function, | 1210 DartinoFunctionBase function, |
| 1211 Selector selector) { | 1211 Selector selector) { |
| 1212 CallStructure callStructure = selector.callStructure; | 1212 CallStructure callStructure = selector.callStructure; |
| 1213 assert(callStructure.signatureApplies(function.signature)); | 1213 assert(callStructure.signatureApplies(function.signature)); |
| 1214 ParameterStubSignature signature = new ParameterStubSignature( | 1214 ParameterStubSignature signature = new ParameterStubSignature( |
| 1215 function.functionId, callStructure); | 1215 function.functionId, callStructure); |
| 1216 FletchFunctionBase stub = systemBuilder.lookupParameterStub(signature); | 1216 DartinoFunctionBase stub = systemBuilder.lookupParameterStub(signature); |
| 1217 if (stub != null) return stub; | 1217 if (stub != null) return stub; |
| 1218 | 1218 |
| 1219 int arity = selector.argumentCount; | 1219 int arity = selector.argumentCount; |
| 1220 if (function.isInstanceMember) arity++; | 1220 if (function.isInstanceMember) arity++; |
| 1221 | 1221 |
| 1222 FletchFunctionBuilder builder = systemBuilder.newFunctionBuilder( | 1222 DartinoFunctionBuilder builder = systemBuilder.newFunctionBuilder( |
| 1223 FletchFunctionKind.PARAMETER_STUB, | 1223 DartinoFunctionKind.PARAMETER_STUB, |
| 1224 arity); | 1224 arity); |
| 1225 | 1225 |
| 1226 BytecodeAssembler assembler = builder.assembler; | 1226 BytecodeAssembler assembler = builder.assembler; |
| 1227 | 1227 |
| 1228 void loadInitializerOrNull(ParameterElement parameter) { | 1228 void loadInitializerOrNull(ParameterElement parameter) { |
| 1229 Expression initializer = parameter.initializer; | 1229 Expression initializer = parameter.initializer; |
| 1230 if (initializer != null) { | 1230 if (initializer != null) { |
| 1231 ConstantExpression expression = context.compileConstant( | 1231 ConstantExpression expression = context.compileConstant( |
| 1232 initializer, | 1232 initializer, |
| 1233 parameter.memberContext.resolvedAst.elements, | 1233 parameter.memberContext.resolvedAst.elements, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1270 // method that takes optional arguments. We really should | 1270 // method that takes optional arguments. We really should |
| 1271 // enumerate all the stubs in the superclasses and make sure | 1271 // enumerate all the stubs in the superclasses and make sure |
| 1272 // they're overridden. | 1272 // they're overridden. |
| 1273 int constId = builder.allocateConstantFromFunction(function.functionId); | 1273 int constId = builder.allocateConstantFromFunction(function.functionId); |
| 1274 assembler | 1274 assembler |
| 1275 ..invokeStatic(constId, index) | 1275 ..invokeStatic(constId, index) |
| 1276 ..ret() | 1276 ..ret() |
| 1277 ..methodEnd(); | 1277 ..methodEnd(); |
| 1278 | 1278 |
| 1279 if (function.isInstanceMember) { | 1279 if (function.isInstanceMember) { |
| 1280 int fletchSelector = context.toFletchSelector(selector); | 1280 int dartinoSelector = context.toDartinoSelector(selector); |
| 1281 FletchClassBuilder classBuilder = getClassBuilderOfExistingClass(function.
memberOf); | 1281 DartinoClassBuilder classBuilder = getClassBuilderOfExistingClass(function
.memberOf); |
| 1282 classBuilder.addToMethodTable(fletchSelector, builder); | 1282 classBuilder.addToMethodTable(dartinoSelector, builder); |
| 1283 | 1283 |
| 1284 // Inject parameter stub into all mixin usages. | 1284 // Inject parameter stub into all mixin usages. |
| 1285 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { | 1285 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { |
| 1286 FletchClassBuilder classBuilder = | 1286 DartinoClassBuilder classBuilder = |
| 1287 systemBuilder.lookupClassBuilderByElement(usage); | 1287 systemBuilder.lookupClassBuilderByElement(usage); |
| 1288 classBuilder.addToMethodTable(fletchSelector, builder); | 1288 classBuilder.addToMethodTable(dartinoSelector, builder); |
| 1289 }); | 1289 }); |
| 1290 } | 1290 } |
| 1291 | 1291 |
| 1292 systemBuilder.registerParameterStub(signature, builder); | 1292 systemBuilder.registerParameterStub(signature, builder); |
| 1293 | 1293 |
| 1294 return builder; | 1294 return builder; |
| 1295 } | 1295 } |
| 1296 | 1296 |
| 1297 /// Create a tear-off getter for [function]. If [isSpecialCallMethod] is | 1297 /// Create a tear-off getter for [function]. If [isSpecialCallMethod] is |
| 1298 /// `true`, this is the special case for `someClosure.call` which should | 1298 /// `true`, this is the special case for `someClosure.call` which should |
| 1299 /// always return `someClosure`. This implies that when [isSpecialCallMethod] | 1299 /// always return `someClosure`. This implies that when [isSpecialCallMethod] |
| 1300 /// is true, we assume [function] is already a member of a closure class (or | 1300 /// is true, we assume [function] is already a member of a closure class (or |
| 1301 /// a class with a `call` method [ClosureKind.functionLike]) and that the | 1301 /// a class with a `call` method [ClosureKind.functionLike]) and that the |
| 1302 /// getter should be added to that class. | 1302 /// getter should be added to that class. |
| 1303 void createTearoffGetterForFunction( | 1303 void createTearoffGetterForFunction( |
| 1304 FletchFunctionBuilder function, | 1304 DartinoFunctionBuilder function, |
| 1305 {bool isSpecialCallMethod}) { | 1305 {bool isSpecialCallMethod}) { |
| 1306 if (isSpecialCallMethod == null) { | 1306 if (isSpecialCallMethod == null) { |
| 1307 throw new ArgumentError("isSpecialCallMethod"); | 1307 throw new ArgumentError("isSpecialCallMethod"); |
| 1308 } | 1308 } |
| 1309 FletchFunctionBuilder getter = systemBuilder.newFunctionBuilder( | 1309 DartinoFunctionBuilder getter = systemBuilder.newFunctionBuilder( |
| 1310 FletchFunctionKind.ACCESSOR, | 1310 DartinoFunctionKind.ACCESSOR, |
| 1311 1); | 1311 1); |
| 1312 // If the getter is of 'call', return the instance instead. | 1312 // If the getter is of 'call', return the instance instead. |
| 1313 if (isSpecialCallMethod) { | 1313 if (isSpecialCallMethod) { |
| 1314 getter.assembler | 1314 getter.assembler |
| 1315 ..loadParameter(0) | 1315 ..loadParameter(0) |
| 1316 ..ret() | 1316 ..ret() |
| 1317 ..methodEnd(); | 1317 ..methodEnd(); |
| 1318 } else { | 1318 } else { |
| 1319 FletchClassBuilder tearoffClass = createTearoffClass(function); | 1319 DartinoClassBuilder tearoffClass = createTearoffClass(function); |
| 1320 int constId = getter.allocateConstantFromClass(tearoffClass.classId); | 1320 int constId = getter.allocateConstantFromClass(tearoffClass.classId); |
| 1321 getter.assembler | 1321 getter.assembler |
| 1322 ..loadParameter(0) | 1322 ..loadParameter(0) |
| 1323 ..allocate(constId, tearoffClass.fields) | 1323 ..allocate(constId, tearoffClass.fields) |
| 1324 ..ret() | 1324 ..ret() |
| 1325 ..methodEnd(); | 1325 ..methodEnd(); |
| 1326 } | 1326 } |
| 1327 // If the name is private, we need the library. | 1327 // If the name is private, we need the library. |
| 1328 // Invariant: We only generate public stubs, e.g. 'call'. | 1328 // Invariant: We only generate public stubs, e.g. 'call'. |
| 1329 LibraryElement library; | 1329 LibraryElement library; |
| 1330 if (function.element != null) { | 1330 if (function.element != null) { |
| 1331 library = function.element.library; | 1331 library = function.element.library; |
| 1332 } | 1332 } |
| 1333 // TODO(sigurdm): Avoid allocating new name here. | 1333 // TODO(sigurdm): Avoid allocating new name here. |
| 1334 Name name = new Name(function.name, library); | 1334 Name name = new Name(function.name, library); |
| 1335 int fletchSelector = context.toFletchSelector( | 1335 int dartinoSelector = context.toDartinoSelector( |
| 1336 new Selector.getter(name)); | 1336 new Selector.getter(name)); |
| 1337 FletchClassBuilder classBuilder = systemBuilder.lookupClassBuilder( | 1337 DartinoClassBuilder classBuilder = systemBuilder.lookupClassBuilder( |
| 1338 function.memberOf); | 1338 function.memberOf); |
| 1339 classBuilder.addToMethodTable(fletchSelector, getter); | 1339 classBuilder.addToMethodTable(dartinoSelector, getter); |
| 1340 | 1340 |
| 1341 // Inject getter into all mixin usages. | 1341 // Inject getter into all mixin usages. |
| 1342 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { | 1342 getMixinApplicationsOfClass(classBuilder).forEach((ClassElement usage) { |
| 1343 FletchClassBuilder classBuilder = | 1343 DartinoClassBuilder classBuilder = |
| 1344 systemBuilder.lookupClassBuilderByElement(usage); | 1344 systemBuilder.lookupClassBuilderByElement(usage); |
| 1345 classBuilder.addToMethodTable(fletchSelector, getter); | 1345 classBuilder.addToMethodTable(dartinoSelector, getter); |
| 1346 }); | 1346 }); |
| 1347 } | 1347 } |
| 1348 | 1348 |
| 1349 void compileTypeTest(ClassElement element, InterfaceType type) { | 1349 void compileTypeTest(ClassElement element, InterfaceType type) { |
| 1350 assert(element.isDeclaration); | 1350 assert(element.isDeclaration); |
| 1351 int fletchSelector = context.toFletchIsSelector(type.element); | 1351 int dartinoSelector = context.toDartinoIsSelector(type.element); |
| 1352 FletchClassBuilder builder = | 1352 DartinoClassBuilder builder = |
| 1353 systemBuilder.lookupClassBuilderByElement(element); | 1353 systemBuilder.lookupClassBuilderByElement(element); |
| 1354 if (builder != null) { | 1354 if (builder != null) { |
| 1355 context.compiler.reportVerboseInfo( | 1355 context.compiler.reportVerboseInfo( |
| 1356 element, 'Adding is-selector for $type'); | 1356 element, 'Adding is-selector for $type'); |
| 1357 builder.addIsSelector(fletchSelector); | 1357 builder.addIsSelector(dartinoSelector); |
| 1358 } | 1358 } |
| 1359 } | 1359 } |
| 1360 | 1360 |
| 1361 int assembleProgram() => 0; | 1361 int assembleProgram() => 0; |
| 1362 | 1362 |
| 1363 FletchDelta computeDelta() { | 1363 DartinoDelta computeDelta() { |
| 1364 | 1364 |
| 1365 if (fletchSystemLibrary == null && compiler.compilationFailed) { | 1365 if (dartinoSystemLibrary == null && compiler.compilationFailed) { |
| 1366 // TODO(ahe): Ensure fletchSystemLibrary is not null. | 1366 // TODO(ahe): Ensure dartinoSystemLibrary is not null. |
| 1367 return null; | 1367 return null; |
| 1368 } | 1368 } |
| 1369 | 1369 |
| 1370 List<VmCommand> commands = <VmCommand>[ | 1370 List<VmCommand> commands = <VmCommand>[ |
| 1371 const NewMap(MapId.methods), | 1371 const NewMap(MapId.methods), |
| 1372 const NewMap(MapId.classes), | 1372 const NewMap(MapId.classes), |
| 1373 const NewMap(MapId.constants), | 1373 const NewMap(MapId.constants), |
| 1374 ]; | 1374 ]; |
| 1375 | 1375 |
| 1376 FletchSystem system = systemBuilder.computeSystem(context, commands); | 1376 DartinoSystem system = systemBuilder.computeSystem(context, commands); |
| 1377 | 1377 |
| 1378 commands.add(const PushNewInteger(0)); | 1378 commands.add(const PushNewInteger(0)); |
| 1379 commands.add(new PushFromMap( | 1379 commands.add(new PushFromMap( |
| 1380 MapId.methods, | 1380 MapId.methods, |
| 1381 system.lookupFunctionByElement(fletchSystemEntry).functionId)); | 1381 system.lookupFunctionByElement(dartinoSystemEntry).functionId)); |
| 1382 | 1382 |
| 1383 return new FletchDelta(system, systemBuilder.predecessorSystem, commands); | 1383 return new DartinoDelta(system, systemBuilder.predecessorSystem, commands); |
| 1384 } | 1384 } |
| 1385 | 1385 |
| 1386 bool enableCodegenWithErrorsIfSupported(Spannable spannable) { | 1386 bool enableCodegenWithErrorsIfSupported(Spannable spannable) { |
| 1387 return true; | 1387 return true; |
| 1388 } | 1388 } |
| 1389 | 1389 |
| 1390 bool enableDeferredLoadingIfSupported(Spannable spannable, Registry registry)
{ | 1390 bool enableDeferredLoadingIfSupported(Spannable spannable, Registry registry)
{ |
| 1391 return false; | 1391 return false; |
| 1392 } | 1392 } |
| 1393 | 1393 |
| 1394 bool registerDeferredLoading(Spannable node, Registry registry) { | 1394 bool registerDeferredLoading(Spannable node, Registry registry) { |
| 1395 compiler.reporter.reportWarningMessage( | 1395 compiler.reporter.reportWarningMessage( |
| 1396 node, | 1396 node, |
| 1397 MessageKind.GENERIC, | 1397 MessageKind.GENERIC, |
| 1398 {'text': "Deferred loading is not supported."}); | 1398 {'text': "Deferred loading is not supported."}); |
| 1399 return false; | 1399 return false; |
| 1400 } | 1400 } |
| 1401 | 1401 |
| 1402 bool get supportsReflection => false; | 1402 bool get supportsReflection => false; |
| 1403 | 1403 |
| 1404 // TODO(sigurdm): Support async/await on the mobile platform. | 1404 // TODO(sigurdm): Support async/await on the mobile platform. |
| 1405 bool get supportsAsyncAwait { | 1405 bool get supportsAsyncAwait { |
| 1406 return !compiler.platformConfigUri.path.contains("embedded"); | 1406 return !compiler.platformConfigUri.path.contains("embedded"); |
| 1407 } | 1407 } |
| 1408 | 1408 |
| 1409 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { | 1409 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
| 1410 if (library.isPlatformLibrary) { | 1410 if (library.isPlatformLibrary) { |
| 1411 String path = library.canonicalUri.path; | 1411 String path = library.canonicalUri.path; |
| 1412 switch(path) { | 1412 switch(path) { |
| 1413 case 'fletch._system': | 1413 case 'dartino._system': |
| 1414 fletchSystemLibrary = library; | 1414 dartinoSystemLibrary = library; |
| 1415 break; | 1415 break; |
| 1416 case 'fletch.ffi': | 1416 case 'dartino.ffi': |
| 1417 fletchFFILibrary = library; | 1417 dartinoFFILibrary = library; |
| 1418 break; | 1418 break; |
| 1419 case 'fletch.collection': | 1419 case 'dartino.collection': |
| 1420 collectionLibrary = library; | 1420 collectionLibrary = library; |
| 1421 break; | 1421 break; |
| 1422 case 'math': | 1422 case 'math': |
| 1423 mathLibrary = library; | 1423 mathLibrary = library; |
| 1424 break; | 1424 break; |
| 1425 case 'fletch': | 1425 case 'dartino': |
| 1426 fletchLibrary = library; | 1426 dartinoLibrary = library; |
| 1427 break; | 1427 break; |
| 1428 } | 1428 } |
| 1429 | 1429 |
| 1430 if (!library.isPatched) { | 1430 if (!library.isPatched) { |
| 1431 // Apply patch, if any. | 1431 // Apply patch, if any. |
| 1432 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); | 1432 Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path); |
| 1433 if (patchUri != null) { | 1433 if (patchUri != null) { |
| 1434 return compiler.patchParser.patchLibrary(loader, patchUri, library); | 1434 return compiler.patchParser.patchLibrary(loader, patchUri, library); |
| 1435 } | 1435 } |
| 1436 } | 1436 } |
| 1437 } | 1437 } |
| 1438 return null; | 1438 return null; |
| 1439 } | 1439 } |
| 1440 | 1440 |
| 1441 bool isBackendLibrary(LibraryElement library) { | 1441 bool isBackendLibrary(LibraryElement library) { |
| 1442 return library == fletchSystemLibrary; | 1442 return library == dartinoSystemLibrary; |
| 1443 } | 1443 } |
| 1444 | 1444 |
| 1445 /// Return non-null to enable patching. Possible return values are 'new' and | 1445 /// Return non-null to enable patching. Possible return values are 'new' and |
| 1446 /// 'old'. Referring to old and new emitter. Since the new emitter is the | 1446 /// 'old'. Referring to old and new emitter. Since the new emitter is the |
| 1447 /// future, we assume 'old' will go away. So it seems the best option for | 1447 /// future, we assume 'old' will go away. So it seems the best option for |
| 1448 /// Fletch is 'new'. | 1448 /// Dartino is 'new'. |
| 1449 String get patchVersion => 'new'; | 1449 String get patchVersion => 'new'; |
| 1450 | 1450 |
| 1451 FunctionElement resolveExternalFunction(FunctionElement element) { | 1451 FunctionElement resolveExternalFunction(FunctionElement element) { |
| 1452 if (element.isPatched) { | 1452 if (element.isPatched) { |
| 1453 FunctionElementX patch = element.patch; | 1453 FunctionElementX patch = element.patch; |
| 1454 compiler.reporter.withCurrentElement(patch, () { | 1454 compiler.reporter.withCurrentElement(patch, () { |
| 1455 patch.parseNode(compiler.parsing); | 1455 patch.parseNode(compiler.parsing); |
| 1456 patch.computeType(compiler.resolution); | 1456 patch.computeType(compiler.resolution); |
| 1457 }); | 1457 }); |
| 1458 element = patch; | 1458 element = patch; |
| 1459 // TODO(ahe): Don't use ensureResolved (fix TODO in isNative instead). | 1459 // TODO(ahe): Don't use ensureResolved (fix TODO in isNative instead). |
| 1460 element.metadata.forEach((m) => m.ensureResolved(compiler.resolution)); | 1460 element.metadata.forEach((m) => m.ensureResolved(compiler.resolution)); |
| 1461 } else if (element.library == fletchSystemLibrary) { | 1461 } else if (element.library == dartinoSystemLibrary) { |
| 1462 // Nothing needed for now. | 1462 // Nothing needed for now. |
| 1463 } else if (element.library == compiler.coreLibrary) { | 1463 } else if (element.library == compiler.coreLibrary) { |
| 1464 // Nothing needed for now. | 1464 // Nothing needed for now. |
| 1465 } else if (element.library == mathLibrary) { | 1465 } else if (element.library == mathLibrary) { |
| 1466 // Nothing needed for now. | 1466 // Nothing needed for now. |
| 1467 } else if (element.library == asyncLibrary) { | 1467 } else if (element.library == asyncLibrary) { |
| 1468 // Nothing needed for now. | 1468 // Nothing needed for now. |
| 1469 } else if (element.library == fletchLibrary) { | 1469 } else if (element.library == dartinoLibrary) { |
| 1470 // Nothing needed for now. | 1470 // Nothing needed for now. |
| 1471 } else if (externals.contains(element)) { | 1471 } else if (externals.contains(element)) { |
| 1472 // Nothing needed for now. | 1472 // Nothing needed for now. |
| 1473 } else { | 1473 } else { |
| 1474 compiler.reporter.reportErrorMessage( | 1474 compiler.reporter.reportErrorMessage( |
| 1475 element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); | 1475 element, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); |
| 1476 } | 1476 } |
| 1477 return element; | 1477 return element; |
| 1478 } | 1478 } |
| 1479 | 1479 |
| 1480 int compileLazyFieldInitializer( | 1480 int compileLazyFieldInitializer( |
| 1481 FieldElement field, | 1481 FieldElement field, |
| 1482 FletchRegistry registry) { | 1482 DartinoRegistry registry) { |
| 1483 int index = context.getStaticFieldIndex(field, null); | 1483 int index = context.getStaticFieldIndex(field, null); |
| 1484 | 1484 |
| 1485 if (field.initializer == null) return index; | 1485 if (field.initializer == null) return index; |
| 1486 | 1486 |
| 1487 if (lazyFieldInitializers.containsKey(field)) return index; | 1487 if (lazyFieldInitializers.containsKey(field)) return index; |
| 1488 | 1488 |
| 1489 FletchFunctionBuilder functionBuilder = systemBuilder.newFunctionBuilder( | 1489 DartinoFunctionBuilder functionBuilder = systemBuilder.newFunctionBuilder( |
| 1490 FletchFunctionKind.LAZY_FIELD_INITIALIZER, | 1490 DartinoFunctionKind.LAZY_FIELD_INITIALIZER, |
| 1491 0, | 1491 0, |
| 1492 name: "${field.name} lazy initializer", | 1492 name: "${field.name} lazy initializer", |
| 1493 element: field); | 1493 element: field); |
| 1494 lazyFieldInitializers[field] = functionBuilder; | 1494 lazyFieldInitializers[field] = functionBuilder; |
| 1495 | 1495 |
| 1496 TreeElements elements = field.resolvedAst.elements; | 1496 TreeElements elements = field.resolvedAst.elements; |
| 1497 | 1497 |
| 1498 ClosureEnvironment closureEnvironment = createClosureEnvironment( | 1498 ClosureEnvironment closureEnvironment = createClosureEnvironment( |
| 1499 field, | 1499 field, |
| 1500 elements); | 1500 elements); |
| 1501 | 1501 |
| 1502 LazyFieldInitializerCodegen codegen = new LazyFieldInitializerCodegen( | 1502 LazyFieldInitializerCodegen codegen = new LazyFieldInitializerCodegen( |
| 1503 functionBuilder, | 1503 functionBuilder, |
| 1504 context, | 1504 context, |
| 1505 elements, | 1505 elements, |
| 1506 registry, | 1506 registry, |
| 1507 closureEnvironment, | 1507 closureEnvironment, |
| 1508 field); | 1508 field); |
| 1509 | 1509 |
| 1510 codegen.compile(); | 1510 codegen.compile(); |
| 1511 | 1511 |
| 1512 return index; | 1512 return index; |
| 1513 } | 1513 } |
| 1514 | 1514 |
| 1515 /// Compiles the initializer part of a constructor. | 1515 /// Compiles the initializer part of a constructor. |
| 1516 /// | 1516 /// |
| 1517 /// See [compilePendingConstructorInitializers] for an overview of how | 1517 /// See [compilePendingConstructorInitializers] for an overview of how |
| 1518 /// constructor initializer and bodies are compiled. | 1518 /// constructor initializer and bodies are compiled. |
| 1519 void compileConstructorInitializer(FletchFunctionBuilder functionBuilder) { | 1519 void compileConstructorInitializer(DartinoFunctionBuilder functionBuilder) { |
| 1520 ConstructorElement constructor = functionBuilder.element; | 1520 ConstructorElement constructor = functionBuilder.element; |
| 1521 assert(constructor.isImplementation); | 1521 assert(constructor.isImplementation); |
| 1522 compiler.reporter.withCurrentElement(constructor, () { | 1522 compiler.reporter.withCurrentElement(constructor, () { |
| 1523 assert(functionBuilder == | 1523 assert(functionBuilder == |
| 1524 systemBuilder.lookupConstructorInitializerByElement(constructor)); | 1524 systemBuilder.lookupConstructorInitializerByElement(constructor)); |
| 1525 context.compiler.reportVerboseInfo( | 1525 context.compiler.reportVerboseInfo( |
| 1526 constructor, 'Compiling constructor initializer $constructor'); | 1526 constructor, 'Compiling constructor initializer $constructor'); |
| 1527 | 1527 |
| 1528 TreeElements elements = constructor.resolvedAst.elements; | 1528 TreeElements elements = constructor.resolvedAst.elements; |
| 1529 | 1529 |
| 1530 // TODO(ahe): We shouldn't create a registry, but we have to as long as | 1530 // TODO(ahe): We shouldn't create a registry, but we have to as long as |
| 1531 // the enqueuer doesn't support elements with more than one compilation | 1531 // the enqueuer doesn't support elements with more than one compilation |
| 1532 // artifact. | 1532 // artifact. |
| 1533 FletchRegistry registry = new FletchRegistry(compiler); | 1533 DartinoRegistry registry = new DartinoRegistry(compiler); |
| 1534 | 1534 |
| 1535 FletchClassBuilder classBuilder = | 1535 DartinoClassBuilder classBuilder = |
| 1536 registerClassElement(constructor.enclosingClass.declaration); | 1536 registerClassElement(constructor.enclosingClass.declaration); |
| 1537 | 1537 |
| 1538 ClosureEnvironment closureEnvironment = | 1538 ClosureEnvironment closureEnvironment = |
| 1539 createClosureEnvironment(constructor, elements); | 1539 createClosureEnvironment(constructor, elements); |
| 1540 | 1540 |
| 1541 ConstructorCodegen codegen = new ConstructorCodegen( | 1541 ConstructorCodegen codegen = new ConstructorCodegen( |
| 1542 functionBuilder, | 1542 functionBuilder, |
| 1543 context, | 1543 context, |
| 1544 elements, | 1544 elements, |
| 1545 registry, | 1545 registry, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1566 /** | 1566 /** |
| 1567 * Generate a setter for field [fieldIndex]. | 1567 * Generate a setter for field [fieldIndex]. |
| 1568 */ | 1568 */ |
| 1569 int makeSetter(int fieldIndex) { | 1569 int makeSetter(int fieldIndex) { |
| 1570 return systemBuilder.getSetterByFieldIndex(fieldIndex); | 1570 return systemBuilder.getSetterByFieldIndex(fieldIndex); |
| 1571 } | 1571 } |
| 1572 | 1572 |
| 1573 void generateUnimplementedError( | 1573 void generateUnimplementedError( |
| 1574 Spannable spannable, | 1574 Spannable spannable, |
| 1575 String reason, | 1575 String reason, |
| 1576 FletchFunctionBuilder function, | 1576 DartinoFunctionBuilder function, |
| 1577 {bool suppressHint: false}) { | 1577 {bool suppressHint: false}) { |
| 1578 if (!suppressHint) { | 1578 if (!suppressHint) { |
| 1579 compiler.reporter.reportHintMessage( | 1579 compiler.reporter.reportHintMessage( |
| 1580 spannable, MessageKind.GENERIC, {'text': reason}); | 1580 spannable, MessageKind.GENERIC, {'text': reason}); |
| 1581 } | 1581 } |
| 1582 var constString = constantSystem.createString( | 1582 var constString = constantSystem.createString( |
| 1583 new DartString.literal(reason)); | 1583 new DartString.literal(reason)); |
| 1584 context.markConstantUsed(constString); | 1584 context.markConstantUsed(constString); |
| 1585 function | 1585 function |
| 1586 ..assembler.loadConst(function.allocateConstant(constString)) | 1586 ..assembler.loadConst(function.allocateConstant(constString)) |
| 1587 ..assembler.emitThrow(); | 1587 ..assembler.emitThrow(); |
| 1588 } | 1588 } |
| 1589 | 1589 |
| 1590 void forEachSubclassOf(ClassElement cls, void f(ClassElement cls)) { | 1590 void forEachSubclassOf(ClassElement cls, void f(ClassElement cls)) { |
| 1591 Queue<ClassElement> queue = new Queue<ClassElement>(); | 1591 Queue<ClassElement> queue = new Queue<ClassElement>(); |
| 1592 queue.add(cls); | 1592 queue.add(cls); |
| 1593 while (queue.isNotEmpty) { | 1593 while (queue.isNotEmpty) { |
| 1594 ClassElement cls = queue.removeFirst(); | 1594 ClassElement cls = queue.removeFirst(); |
| 1595 if (compiler.world.isInstantiated(cls.declaration)) { | 1595 if (compiler.world.isInstantiated(cls.declaration)) { |
| 1596 queue.addAll(compiler.world.strictSubclassesOf(cls)); | 1596 queue.addAll(compiler.world.strictSubclassesOf(cls)); |
| 1597 } | 1597 } |
| 1598 f(cls); | 1598 f(cls); |
| 1599 } | 1599 } |
| 1600 } | 1600 } |
| 1601 | 1601 |
| 1602 void newElement(Element element) { | 1602 void newElement(Element element) { |
| 1603 if (element.isField && element.isInstanceMember) { | 1603 if (element.isField && element.isInstanceMember) { |
| 1604 forEachSubclassOf(element.enclosingClass, (ClassElement cls) { | 1604 forEachSubclassOf(element.enclosingClass, (ClassElement cls) { |
| 1605 FletchClassBuilder builder = registerClassElement(cls); | 1605 DartinoClassBuilder builder = registerClassElement(cls); |
| 1606 builder.addField(element); | 1606 builder.addField(element); |
| 1607 }); | 1607 }); |
| 1608 } | 1608 } |
| 1609 } | 1609 } |
| 1610 | 1610 |
| 1611 void replaceFunctionUsageElement(Element element, List<Element> users) { | 1611 void replaceFunctionUsageElement(Element element, List<Element> users) { |
| 1612 for (Element user in users) { | 1612 for (Element user in users) { |
| 1613 systemBuilder.replaceUsage(user, element); | 1613 systemBuilder.replaceUsage(user, element); |
| 1614 } | 1614 } |
| 1615 } | 1615 } |
| 1616 | 1616 |
| 1617 void forgetElement(Element element) { | 1617 void forgetElement(Element element) { |
| 1618 // TODO(ahe): The front-end should remove the element from | 1618 // TODO(ahe): The front-end should remove the element from |
| 1619 // elementsWithCompileTimeErrors. | 1619 // elementsWithCompileTimeErrors. |
| 1620 compiler.elementsWithCompileTimeErrors.remove(element); | 1620 compiler.elementsWithCompileTimeErrors.remove(element); |
| 1621 FletchFunctionBase function = | 1621 DartinoFunctionBase function = |
| 1622 systemBuilder.lookupFunctionByElement(element); | 1622 systemBuilder.lookupFunctionByElement(element); |
| 1623 if (function == null) return; | 1623 if (function == null) return; |
| 1624 systemBuilder.forgetFunction(function); | 1624 systemBuilder.forgetFunction(function); |
| 1625 } | 1625 } |
| 1626 | 1626 |
| 1627 void removeField(FieldElement element) { | 1627 void removeField(FieldElement element) { |
| 1628 if (!element.isInstanceMember) return; | 1628 if (!element.isInstanceMember) return; |
| 1629 ClassElement enclosingClass = element.enclosingClass; | 1629 ClassElement enclosingClass = element.enclosingClass; |
| 1630 forEachSubclassOf(enclosingClass, (ClassElement cls) { | 1630 forEachSubclassOf(enclosingClass, (ClassElement cls) { |
| 1631 FletchClassBuilder builder = registerClassElement(cls); | 1631 DartinoClassBuilder builder = registerClassElement(cls); |
| 1632 builder.removeField(element); | 1632 builder.removeField(element); |
| 1633 }); | 1633 }); |
| 1634 } | 1634 } |
| 1635 | 1635 |
| 1636 void removeFunction(FunctionElement element) { | 1636 void removeFunction(FunctionElement element) { |
| 1637 FletchFunctionBase function = | 1637 DartinoFunctionBase function = |
| 1638 systemBuilder.lookupFunctionByElement(element); | 1638 systemBuilder.lookupFunctionByElement(element); |
| 1639 if (function == null) return; | 1639 if (function == null) return; |
| 1640 if (element.isInstanceMember) { | 1640 if (element.isInstanceMember) { |
| 1641 ClassElement enclosingClass = element.enclosingClass; | 1641 ClassElement enclosingClass = element.enclosingClass; |
| 1642 FletchClassBuilder builder = registerClassElement(enclosingClass); | 1642 DartinoClassBuilder builder = registerClassElement(enclosingClass); |
| 1643 builder.removeFromMethodTable(function); | 1643 builder.removeFromMethodTable(function); |
| 1644 } | 1644 } |
| 1645 } | 1645 } |
| 1646 | 1646 |
| 1647 /// Invoked during codegen enqueuing to compile constructor initializers. | 1647 /// Invoked during codegen enqueuing to compile constructor initializers. |
| 1648 /// | 1648 /// |
| 1649 /// There's only one [Element] representing a constructor, but Fletch uses | 1649 /// There's only one [Element] representing a constructor, but Dartino uses |
| 1650 /// two different functions for implementing a constructor. | 1650 /// two different functions for implementing a constructor. |
| 1651 /// | 1651 /// |
| 1652 /// The first function takes care of allocating the instance and initializing | 1652 /// The first function takes care of allocating the instance and initializing |
| 1653 /// fields (called the constructor initializer), the other function | 1653 /// fields (called the constructor initializer), the other function |
| 1654 /// implements the body of the constructor (what is between the curly | 1654 /// implements the body of the constructor (what is between the curly |
| 1655 /// braces). A constructor initializer never calls constructor initializers | 1655 /// braces). A constructor initializer never calls constructor initializers |
| 1656 /// of a superclass. Instead field initializers from the superclass are | 1656 /// of a superclass. Instead field initializers from the superclass are |
| 1657 /// inlined in the constructor initializer. The constructor initializer will | 1657 /// inlined in the constructor initializer. The constructor initializer will |
| 1658 /// call all the constructor bodies from superclasses in the correct order. | 1658 /// call all the constructor bodies from superclasses in the correct order. |
| 1659 /// | 1659 /// |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1672 } | 1672 } |
| 1673 } | 1673 } |
| 1674 | 1674 |
| 1675 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { | 1675 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) { |
| 1676 if (enqueuer is! ResolutionEnqueuer) { | 1676 if (enqueuer is! ResolutionEnqueuer) { |
| 1677 compilePendingConstructorInitializers(); | 1677 compilePendingConstructorInitializers(); |
| 1678 } | 1678 } |
| 1679 return true; | 1679 return true; |
| 1680 } | 1680 } |
| 1681 | 1681 |
| 1682 FletchEnqueueTask makeEnqueuer() => new FletchEnqueueTask(compiler); | 1682 DartinoEnqueueTask makeEnqueuer() => new DartinoEnqueueTask(compiler); |
| 1683 | 1683 |
| 1684 static bool isExactParameterMatch( | 1684 static bool isExactParameterMatch( |
| 1685 FunctionSignature signature, | 1685 FunctionSignature signature, |
| 1686 CallStructure callStructure) { | 1686 CallStructure callStructure) { |
| 1687 if (!callStructure.signatureApplies(signature)) { | 1687 if (!callStructure.signatureApplies(signature)) { |
| 1688 return false; | 1688 return false; |
| 1689 } | 1689 } |
| 1690 if (!signature.hasOptionalParameters) { | 1690 if (!signature.hasOptionalParameters) { |
| 1691 // There are no optional parameters, and the signature applies, so this | 1691 // There are no optional parameters, and the signature applies, so this |
| 1692 // is an exact match. | 1692 // is an exact match. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1705 signature.optionalParameterCount) { | 1705 signature.optionalParameterCount) { |
| 1706 return false; | 1706 return false; |
| 1707 } | 1707 } |
| 1708 int index = 0; | 1708 int index = 0; |
| 1709 for (var parameter in signature.orderedOptionalParameters) { | 1709 for (var parameter in signature.orderedOptionalParameters) { |
| 1710 if (parameter.name != callStructure.namedArguments[index++]) return false; | 1710 if (parameter.name != callStructure.namedArguments[index++]) return false; |
| 1711 } | 1711 } |
| 1712 return true; | 1712 return true; |
| 1713 } | 1713 } |
| 1714 | 1714 |
| 1715 static FletchBackend createInstance(FletchCompilerImplementation compiler) { | 1715 static DartinoBackend createInstance(DartinoCompilerImplementation compiler) { |
| 1716 return new FletchBackend(compiler); | 1716 return new DartinoBackend(compiler); |
| 1717 } | 1717 } |
| 1718 | 1718 |
| 1719 Uri resolvePatchUri(String libraryName, Uri libraryRoot) { | 1719 Uri resolvePatchUri(String libraryName, Uri libraryRoot) { |
| 1720 throw "Not implemented"; | 1720 throw "Not implemented"; |
| 1721 } | 1721 } |
| 1722 | 1722 |
| 1723 } | 1723 } |
| 1724 | 1724 |
| 1725 class FletchImpactTransformer extends ImpactTransformer { | 1725 class DartinoImpactTransformer extends ImpactTransformer { |
| 1726 final FletchBackend backend; | 1726 final DartinoBackend backend; |
| 1727 | 1727 |
| 1728 FletchImpactTransformer(this.backend); | 1728 DartinoImpactTransformer(this.backend); |
| 1729 | 1729 |
| 1730 @override | 1730 @override |
| 1731 WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) { | 1731 WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) { |
| 1732 TransformedWorldImpact transformed = | 1732 TransformedWorldImpact transformed = |
| 1733 new TransformedWorldImpact(worldImpact); | 1733 new TransformedWorldImpact(worldImpact); |
| 1734 | 1734 |
| 1735 bool anyChange = false; | 1735 bool anyChange = false; |
| 1736 | 1736 |
| 1737 if (worldImpact.constSymbolNames.isNotEmpty) { | 1737 if (worldImpact.constSymbolNames.isNotEmpty) { |
| 1738 ClassElement symbolClass = | 1738 ClassElement symbolClass = |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1768 return element.memberContext != element; | 1768 return element.memberContext != element; |
| 1769 } | 1769 } |
| 1770 return false; | 1770 return false; |
| 1771 } | 1771 } |
| 1772 | 1772 |
| 1773 Name memberName(AstElement element) { | 1773 Name memberName(AstElement element) { |
| 1774 if (isLocalFunction(element)) return null; | 1774 if (isLocalFunction(element)) return null; |
| 1775 MemberElement member = element; | 1775 MemberElement member = element; |
| 1776 return member.memberName; | 1776 return member.memberName; |
| 1777 } | 1777 } |
| OLD | NEW |