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