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