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