Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: pkg/fletchc/lib/src/fletch_backend.dart

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

Powered by Google App Engine
This is Rietveld 408576698