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

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

Issue 1170123004: Rename CompiledFunction to FletchFunctionBuilder and CompiledClass to FletchClassBuilder. (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: Created 5 years, 6 months 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 'package:compiler/src/dart2jslib.dart' show 10 import 'package:compiler/src/dart2jslib.dart' show
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 TreeElements; 81 TreeElements;
82 82
83 import 'package:compiler/src/library_loader.dart' show 83 import 'package:compiler/src/library_loader.dart' show
84 LibraryLoader; 84 LibraryLoader;
85 85
86 import 'fletch_constants.dart' show 86 import 'fletch_constants.dart' show
87 FletchClassConstant, 87 FletchClassConstant,
88 FletchFunctionConstant, 88 FletchFunctionConstant,
89 FletchClassInstanceConstant; 89 FletchClassInstanceConstant;
90 90
91 import 'compiled_function.dart' show 91 import 'fletch_function_builder.dart' show
92 CompiledFunctionKind, 92 FletchFunctionBuilderKind,
93 CompiledFunction, 93 FletchFunctionBuilder,
94 DebugInfo; 94 DebugInfo;
95 95
96 import 'compiled_class.dart' show 96 import 'fletch_class_builder.dart' show
97 CompiledClass; 97 FletchClassBuilder;
98 98
99 import 'codegen_visitor.dart'; 99 import 'codegen_visitor.dart';
100 import 'debug_info.dart'; 100 import 'debug_info.dart';
101 import 'debug_info_constructor_codegen.dart'; 101 import 'debug_info_constructor_codegen.dart';
102 import 'debug_info_function_codegen.dart'; 102 import 'debug_info_function_codegen.dart';
103 import 'debug_info_lazy_field_initializer_codegen.dart'; 103 import 'debug_info_lazy_field_initializer_codegen.dart';
104 import 'fletch_context.dart'; 104 import 'fletch_context.dart';
105 import 'fletch_selector.dart'; 105 import 'fletch_selector.dart';
106 import 'function_codegen.dart'; 106 import 'function_codegen.dart';
107 import 'lazy_field_initializer_codegen.dart'; 107 import 'lazy_field_initializer_codegen.dart';
108 import 'constructor_codegen.dart'; 108 import 'constructor_codegen.dart';
109 import 'closure_environment.dart'; 109 import 'closure_environment.dart';
110 import '../bytecodes.dart'; 110 import '../bytecodes.dart';
111 import '../commands.dart'; 111 import '../commands.dart';
112 112
113 class FletchBackend extends Backend { 113 class FletchBackend extends Backend {
114 static const String growableListName = '_GrowableList'; 114 static const String growableListName = '_GrowableList';
115 static const String constantListName = '_ConstantList'; 115 static const String constantListName = '_ConstantList';
116 static const String constantMapName = '_ConstantMap'; 116 static const String constantMapName = '_ConstantMap';
117 static const String linkedHashMapName = '_CompactLinkedHashMap'; 117 static const String linkedHashMapName = '_CompactLinkedHashMap';
118 static const String noSuchMethodName = '_noSuchMethod'; 118 static const String noSuchMethodName = '_noSuchMethod';
119 static const String noSuchMethodTrampolineName = '_noSuchMethodTrampoline'; 119 static const String noSuchMethodTrampolineName = '_noSuchMethodTrampoline';
120 120
121 final FletchContext context; 121 final FletchContext context;
122 122
123 final DartConstantTask constantCompilerTask; 123 final DartConstantTask constantCompilerTask;
124 124
125 final Map<FunctionElement, CompiledFunction> compiledFunctions = 125 final Map<FunctionElement, FletchFunctionBuilder> functionBuilders =
126 <FunctionElement, CompiledFunction>{}; 126 <FunctionElement, FletchFunctionBuilder>{};
127 127
128 final Map<ConstructorElement, CompiledFunction> constructors = 128 final Map<ConstructorElement, FletchFunctionBuilder> constructors =
129 <ConstructorElement, CompiledFunction>{}; 129 <ConstructorElement, FletchFunctionBuilder>{};
130 130
131 final List<CompiledFunction> functions = <CompiledFunction>[]; 131 final List<FletchFunctionBuilder> functions = <FletchFunctionBuilder>[];
132 132
133 final Set<FunctionElement> externals = new Set<FunctionElement>(); 133 final Set<FunctionElement> externals = new Set<FunctionElement>();
134 134
135 final Map<ClassElement, CompiledClass> compiledClasses = 135 final Map<ClassElement, FletchClassBuilder> classBuilders =
136 <ClassElement, CompiledClass>{}; 136 <ClassElement, FletchClassBuilder>{};
137 final Map<ClassElement, Set<ClassElement>> directSubclasses = 137 final Map<ClassElement, Set<ClassElement>> directSubclasses =
138 <ClassElement, Set<ClassElement>>{}; 138 <ClassElement, Set<ClassElement>>{};
139 139
140 final List<CompiledClass> classes = <CompiledClass>[]; 140 final List<FletchClassBuilder> classes = <FletchClassBuilder>[];
141 141
142 final Set<ClassElement> builtinClasses = new Set<ClassElement>(); 142 final Set<ClassElement> builtinClasses = new Set<ClassElement>();
143 143
144 final Map<MemberElement, ClosureEnvironment> closureEnvironments = 144 final Map<MemberElement, ClosureEnvironment> closureEnvironments =
145 <MemberElement, ClosureEnvironment>{}; 145 <MemberElement, ClosureEnvironment>{};
146 146
147 final Map<FunctionElement, CompiledClass> closureClasses = 147 final Map<FunctionElement, FletchClassBuilder> closureClasses =
148 <FunctionElement, CompiledClass>{}; 148 <FunctionElement, FletchClassBuilder>{};
149 149
150 final Map<FieldElement, CompiledFunction> lazyFieldInitializers = 150 final Map<FieldElement, FletchFunctionBuilder> lazyFieldInitializers =
151 <FieldElement, CompiledFunction>{}; 151 <FieldElement, FletchFunctionBuilder>{};
152 152
153 final Map<CompiledFunction, CompiledClass> tearoffClasses = 153 final Map<FletchFunctionBuilder, FletchClassBuilder> tearoffClasses =
154 <CompiledFunction, CompiledClass>{}; 154 <FletchFunctionBuilder, FletchClassBuilder>{};
155 155
156 final Map<int, int> getters = <int, int>{}; 156 final Map<int, int> getters = <int, int>{};
157 final Map<int, int> setters = <int, int>{}; 157 final Map<int, int> setters = <int, int>{};
158 158
159 Map<CompiledClass, CompiledFunction> tearoffFunctions; 159 Map<FletchClassBuilder, FletchFunctionBuilder> tearoffFunctions;
160 160
161 List<Command> commands; 161 List<Command> commands;
162 162
163 LibraryElement fletchSystemLibrary; 163 LibraryElement fletchSystemLibrary;
164 LibraryElement fletchFFILibrary; 164 LibraryElement fletchFFILibrary;
165 LibraryElement fletchIOSystemLibrary; 165 LibraryElement fletchIOSystemLibrary;
166 LibraryElement collectionLibrary; 166 LibraryElement collectionLibrary;
167 LibraryElement mathLibrary; 167 LibraryElement mathLibrary;
168 168
169 FunctionElement fletchSystemEntry; 169 FunctionElement fletchSystemEntry;
170 170
171 FunctionElement fletchExternalInvokeMain; 171 FunctionElement fletchExternalInvokeMain;
172 172
173 FunctionElement fletchExternalYield; 173 FunctionElement fletchExternalYield;
174 174
175 FunctionElement fletchExternalNativeError; 175 FunctionElement fletchExternalNativeError;
176 176
177 FunctionElement fletchExternalCoroutineChange; 177 FunctionElement fletchExternalCoroutineChange;
178 178
179 FunctionElement fletchUnresolved; 179 FunctionElement fletchUnresolved;
180 FunctionElement fletchCompileError; 180 FunctionElement fletchCompileError;
181 181
182 CompiledClass compiledObjectClass; 182 FletchClassBuilder compiledObjectClass;
183 183
184 ClassElement stringClass; 184 ClassElement stringClass;
185 ClassElement smiClass; 185 ClassElement smiClass;
186 ClassElement mintClass; 186 ClassElement mintClass;
187 ClassElement growableListClass; 187 ClassElement growableListClass;
188 ClassElement linkedHashMapClass; 188 ClassElement linkedHashMapClass;
189 ClassElement coroutineClass; 189 ClassElement coroutineClass;
190 190
191 final Set<FunctionElement> alwaysEnqueue = new Set<FunctionElement>(); 191 final Set<FunctionElement> alwaysEnqueue = new Set<FunctionElement>();
192 192
193 FletchBackend(FletchCompiler compiler) 193 FletchBackend(FletchCompiler compiler)
194 : this.context = compiler.context, 194 : this.context = compiler.context,
195 this.constantCompilerTask = new DartConstantTask(compiler), 195 this.constantCompilerTask = new DartConstantTask(compiler),
196 super(compiler) { 196 super(compiler) {
197 context.resolutionCallbacks = new FletchResolutionCallbacks(context); 197 context.resolutionCallbacks = new FletchResolutionCallbacks(context);
198 } 198 }
199 199
200 CompiledClass registerClassElement(ClassElement element) { 200 FletchClassBuilder registerClassElement(ClassElement element) {
201 if (element == null) return null; 201 if (element == null) return null;
202 assert(element.isDeclaration); 202 assert(element.isDeclaration);
203 return compiledClasses.putIfAbsent(element, () { 203 return classBuilders.putIfAbsent(element, () {
204 directSubclasses[element] = new Set<ClassElement>(); 204 directSubclasses[element] = new Set<ClassElement>();
205 CompiledClass superclass = registerClassElement(element.superclass); 205 FletchClassBuilder superclass = registerClassElement(element.superclass);
206 if (superclass != null) { 206 if (superclass != null) {
207 Set<ClassElement> subclasses = directSubclasses[element.superclass]; 207 Set<ClassElement> subclasses = directSubclasses[element.superclass];
208 subclasses.add(element); 208 subclasses.add(element);
209 } 209 }
210 int id = classes.length; 210 int id = classes.length;
211 CompiledClass compiledClass = new CompiledClass(id, element, superclass); 211 FletchClassBuilder classBuilder = new FletchClassBuilder(
212 id, element, superclass);
212 if (element.lookupLocalMember(Compiler.CALL_OPERATOR_NAME) != null) { 213 if (element.lookupLocalMember(Compiler.CALL_OPERATOR_NAME) != null) {
213 compiledClass.createIsFunctionEntry(this); 214 classBuilder.createIsFunctionEntry(this);
214 } 215 }
215 classes.add(compiledClass); 216 classes.add(classBuilder);
216 return compiledClass; 217 return classBuilder;
217 }); 218 });
218 } 219 }
219 220
220 CompiledClass createCallableStubClass(int fields, CompiledClass superclass) { 221 FletchClassBuilder createCallableStubClass(
222 int fields, FletchClassBuilder superclass) {
221 int id = classes.length; 223 int id = classes.length;
222 CompiledClass compiledClass = new CompiledClass( 224 FletchClassBuilder classBuilder = new FletchClassBuilder(
223 id, null, superclass, extraFields: fields); 225 id, null, superclass, extraFields: fields);
224 classes.add(compiledClass); 226 classes.add(classBuilder);
225 compiledClass.createIsFunctionEntry(this); 227 classBuilder.createIsFunctionEntry(this);
226 return compiledClass; 228 return classBuilder;
227 } 229 }
228 230
229 FletchResolutionCallbacks get resolutionCallbacks { 231 FletchResolutionCallbacks get resolutionCallbacks {
230 return context.resolutionCallbacks; 232 return context.resolutionCallbacks;
231 } 233 }
232 234
233 List<CompilerTask> get tasks => <CompilerTask>[]; 235 List<CompilerTask> get tasks => <CompilerTask>[];
234 236
235 ConstantSystem get constantSystem { 237 ConstantSystem get constantSystem {
236 return constantCompilerTask.constantCompiler.constantSystem; 238 return constantCompilerTask.constantCompiler.constantSystem;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 } 276 }
275 fletchExternalInvokeMain = findExternal('invokeMain'); 277 fletchExternalInvokeMain = findExternal('invokeMain');
276 fletchExternalYield = findExternal('yield'); 278 fletchExternalYield = findExternal('yield');
277 fletchExternalCoroutineChange = findExternal('coroutineChange'); 279 fletchExternalCoroutineChange = findExternal('coroutineChange');
278 fletchExternalNativeError = findExternal('nativeError'); 280 fletchExternalNativeError = findExternal('nativeError');
279 fletchUnresolved = findExternal('unresolved'); 281 fletchUnresolved = findExternal('unresolved');
280 world.registerStaticUse(fletchUnresolved); 282 world.registerStaticUse(fletchUnresolved);
281 fletchCompileError = findExternal('compileError'); 283 fletchCompileError = findExternal('compileError');
282 world.registerStaticUse(fletchCompileError); 284 world.registerStaticUse(fletchCompileError);
283 285
284 CompiledClass loadClass(String name, LibraryElement library) { 286 FletchClassBuilder loadClass(String name, LibraryElement library) {
285 var classImpl = library.findLocal(name); 287 var classImpl = library.findLocal(name);
286 if (classImpl == null) classImpl = library.implementation.find(name); 288 if (classImpl == null) classImpl = library.implementation.find(name);
287 if (classImpl == null) { 289 if (classImpl == null) {
288 compiler.internalError(library, "Internal class '$name' not found."); 290 compiler.internalError(library, "Internal class '$name' not found.");
289 return null; 291 return null;
290 } 292 }
291 // TODO(ahe): Register in ResolutionCallbacks. The 3 lines below should 293 // TODO(ahe): Register in ResolutionCallbacks. The 3 lines below should
292 // not happen at this point in time. 294 // not happen at this point in time.
293 classImpl.ensureResolved(compiler); 295 classImpl.ensureResolved(compiler);
294 CompiledClass compiledClass = registerClassElement(classImpl); 296 FletchClassBuilder classBuilder = registerClassElement(classImpl);
295 world.registerInstantiatedType(classImpl.rawType, registry); 297 world.registerInstantiatedType(classImpl.rawType, registry);
296 // TODO(ahe): This is a hack to let both the world and the codegen know 298 // TODO(ahe): This is a hack to let both the world and the codegen know
297 // about the instantiated type. 299 // about the instantiated type.
298 registry.registerInstantiatedType(classImpl.rawType); 300 registry.registerInstantiatedType(classImpl.rawType);
299 return compiledClass; 301 return classBuilder;
300 } 302 }
301 303
302 CompiledClass loadBuiltinClass(String name, LibraryElement library) { 304 FletchClassBuilder loadBuiltinClass(String name, LibraryElement library) {
303 CompiledClass compiledClass = loadClass(name, library); 305 FletchClassBuilder classBuilder = loadClass(name, library);
304 builtinClasses.add(compiledClass.element); 306 builtinClasses.add(classBuilder.element);
305 return compiledClass; 307 return classBuilder;
306 } 308 }
307 309
308 compiledObjectClass = loadBuiltinClass("Object", compiler.coreLibrary); 310 compiledObjectClass = loadBuiltinClass("Object", compiler.coreLibrary);
309 smiClass = loadBuiltinClass("_Smi", compiler.coreLibrary).element; 311 smiClass = loadBuiltinClass("_Smi", compiler.coreLibrary).element;
310 mintClass = loadBuiltinClass("_Mint", compiler.coreLibrary).element; 312 mintClass = loadBuiltinClass("_Mint", compiler.coreLibrary).element;
311 stringClass = loadBuiltinClass("_StringImpl", compiler.coreLibrary).element; 313 stringClass = loadBuiltinClass("_StringImpl", compiler.coreLibrary).element;
312 // TODO(ahe): Register _ConstantList through ResolutionCallbacks. 314 // TODO(ahe): Register _ConstantList through ResolutionCallbacks.
313 loadBuiltinClass(constantListName, fletchSystemLibrary); 315 loadBuiltinClass(constantListName, fletchSystemLibrary);
314 loadBuiltinClass(constantMapName, fletchSystemLibrary); 316 loadBuiltinClass(constantMapName, fletchSystemLibrary);
315 loadBuiltinClass("_DoubleImpl", compiler.coreLibrary); 317 loadBuiltinClass("_DoubleImpl", compiler.coreLibrary);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 /// The patch parser (pkg/compiler/lib/src/patch_parser.dart). The patch 366 /// The patch parser (pkg/compiler/lib/src/patch_parser.dart). The patch
365 /// parser looks for an annotation on the form "@patch", where "patch" is 367 /// parser looks for an annotation on the form "@patch", where "patch" is
366 /// compile-time constant instance of [patchAnnotationClass]. 368 /// compile-time constant instance of [patchAnnotationClass].
367 ClassElement get patchAnnotationClass { 369 ClassElement get patchAnnotationClass {
368 // TODO(ahe): Introduce a proper constant class to identify constants. For 370 // TODO(ahe): Introduce a proper constant class to identify constants. For
369 // now, we simply put "const patch = "patch";" in the beginning of patch 371 // now, we simply put "const patch = "patch";" in the beginning of patch
370 // files. 372 // files.
371 return super.stringImplementation; 373 return super.stringImplementation;
372 } 374 }
373 375
374 CompiledClass createClosureClass( 376 FletchClassBuilder createClosureClass(
375 FunctionElement closure, 377 FunctionElement closure,
376 ClosureEnvironment closureEnvironment) { 378 ClosureEnvironment closureEnvironment) {
377 return closureClasses.putIfAbsent(closure, () { 379 return closureClasses.putIfAbsent(closure, () {
378 ClosureInfo info = closureEnvironment.closures[closure]; 380 ClosureInfo info = closureEnvironment.closures[closure];
379 int fields = info.free.length; 381 int fields = info.free.length;
380 if (info.isThisFree) fields++; 382 if (info.isThisFree) fields++;
381 return createCallableStubClass(fields, compiledObjectClass); 383 return createCallableStubClass(fields, compiledObjectClass);
382 }); 384 });
383 } 385 }
384 386
385 /** 387 /**
386 * Create a tearoff class for function [function]. 388 * Create a tearoff class for function [function].
387 * 389 *
388 * The class will have one method named 'call', accepting the same arguments 390 * The class will have one method named 'call', accepting the same arguments
389 * as [function]. The method will load the arguments received and statically 391 * as [function]. The method will load the arguments received and statically
390 * call [function] (essential a tail-call). 392 * call [function] (essential a tail-call).
391 * 393 *
392 * If [function] is an instance member, the class will have one field, the 394 * If [function] is an instance member, the class will have one field, the
393 * instance. 395 * instance.
394 */ 396 */
395 CompiledClass createTearoffClass(CompiledFunction function) { 397 FletchClassBuilder createTearoffClass(FletchFunctionBuilder function) {
396 return tearoffClasses.putIfAbsent(function, () { 398 return tearoffClasses.putIfAbsent(function, () {
397 FunctionSignature signature = function.signature; 399 FunctionSignature signature = function.signature;
398 bool hasThis = function.hasThisArgument; 400 bool hasThis = function.hasThisArgument;
399 CompiledClass compiledClass = createCallableStubClass( 401 FletchClassBuilder classBuilder = createCallableStubClass(
400 hasThis ? 1 : 0, 402 hasThis ? 1 : 0,
401 compiledObjectClass); 403 compiledObjectClass);
402 CompiledFunction compiledFunction = new CompiledFunction( 404 FletchFunctionBuilder functionBuilder = new FletchFunctionBuilder(
403 functions.length, 405 functions.length,
404 'call', 406 'call',
405 null, 407 null,
406 signature, 408 signature,
407 compiledClass); 409 classBuilder);
408 functions.add(compiledFunction); 410 functions.add(functionBuilder);
409 411
410 BytecodeBuilder builder = compiledFunction.builder; 412 BytecodeBuilder builder = functionBuilder.builder;
411 int argumentCount = signature.parameterCount; 413 int argumentCount = signature.parameterCount;
412 if (hasThis) { 414 if (hasThis) {
413 argumentCount++; 415 argumentCount++;
414 // If the tearoff has a 'this' value, load it. It's the only field 416 // If the tearoff has a 'this' value, load it. It's the only field
415 // in the tearoff class. 417 // in the tearoff class.
416 builder 418 builder
417 ..loadParameter(0) 419 ..loadParameter(0)
418 ..loadField(0); 420 ..loadField(0);
419 } 421 }
420 for (int i = 0; i < signature.parameterCount; i++) { 422 for (int i = 0; i < signature.parameterCount; i++) {
421 // The closure-class is at parameter index 0, so argument i is at 423 // The closure-class is at parameter index 0, so argument i is at
422 // i + 1. 424 // i + 1.
423 builder.loadParameter(i + 1); 425 builder.loadParameter(i + 1);
424 } 426 }
425 int constId = compiledFunction.allocateConstantFromFunction( 427 int constId = functionBuilder.allocateConstantFromFunction(
426 function.methodId); 428 function.methodId);
427 // TODO(ajohnsen): Create a tail-call bytecode, so we don't have to 429 // TODO(ajohnsen): Create a tail-call bytecode, so we don't have to
428 // load all the arguments. 430 // load all the arguments.
429 builder 431 builder
430 ..invokeStatic(constId, argumentCount) 432 ..invokeStatic(constId, argumentCount)
431 ..ret() 433 ..ret()
432 ..methodEnd(); 434 ..methodEnd();
433 435
434 String symbol = context.getCallSymbol(signature); 436 String symbol = context.getCallSymbol(signature);
435 int id = context.getSymbolId(symbol); 437 int id = context.getSymbolId(symbol);
436 int fletchSelector = FletchSelector.encodeMethod( 438 int fletchSelector = FletchSelector.encodeMethod(
437 id, 439 id,
438 signature.parameterCount); 440 signature.parameterCount);
439 compiledClass.addToMethodTable(fletchSelector, compiledFunction); 441 classBuilder.addToMethodTable(fletchSelector, functionBuilder);
440 442
441 if (hasThis && function.memberOf.element != null) { 443 if (hasThis && function.memberOf.element != null) {
442 // Create == function that tests for equality. 444 // Create == function that tests for equality.
443 int isSelector = context.toFletchTearoffIsSelector( 445 int isSelector = context.toFletchTearoffIsSelector(
444 function.name, 446 function.name,
445 function.memberOf.element); 447 function.memberOf.element);
446 compiledClass.addIsSelector(isSelector); 448 classBuilder.addIsSelector(isSelector);
447 449
448 CompiledFunction equal = new CompiledFunction.normal( 450 FletchFunctionBuilder equal = new FletchFunctionBuilder.normal(
449 functions.length, 451 functions.length,
450 2); 452 2);
451 functions.add(equal); 453 functions.add(equal);
452 454
453 BytecodeLabel isFalse = new BytecodeLabel(); 455 BytecodeLabel isFalse = new BytecodeLabel();
454 equal.builder 456 equal.builder
455 // First test for class. This ensures it's the exact function that 457 // First test for class. This ensures it's the exact function that
456 // we expect. 458 // we expect.
457 ..loadParameter(1) 459 ..loadParameter(1)
458 ..invokeTest(isSelector, 0) 460 ..invokeTest(isSelector, 0)
459 ..branchIfFalse(isFalse) 461 ..branchIfFalse(isFalse)
460 // Then test that the receiver is identical. 462 // Then test that the receiver is identical.
461 ..loadParameter(0) 463 ..loadParameter(0)
462 ..loadField(0) 464 ..loadField(0)
463 ..loadParameter(1) 465 ..loadParameter(1)
464 ..loadField(0) 466 ..loadField(0)
465 ..identicalNonNumeric() 467 ..identicalNonNumeric()
466 ..branchIfFalse(isFalse) 468 ..branchIfFalse(isFalse)
467 ..loadLiteralTrue() 469 ..loadLiteralTrue()
468 ..ret() 470 ..ret()
469 ..bind(isFalse) 471 ..bind(isFalse)
470 ..loadLiteralFalse() 472 ..loadLiteralFalse()
471 ..ret() 473 ..ret()
472 ..methodEnd(); 474 ..methodEnd();
473 475
474 int id = context.getSymbolId("=="); 476 int id = context.getSymbolId("==");
475 int equalsSelector = FletchSelector.encodeMethod(id, 1); 477 int equalsSelector = FletchSelector.encodeMethod(id, 1);
476 compiledClass.addToMethodTable(equalsSelector, equal); 478 classBuilder.addToMethodTable(equalsSelector, equal);
477 479
478 // Create hashCode getter. We simply xor the object hashCode and the 480 // Create hashCode getter. We simply xor the object hashCode and the
479 // method id of the tearoff'ed function. 481 // method id of the tearoff'ed function.
480 CompiledFunction hashCode = new CompiledFunction.accessor( 482 FletchFunctionBuilder hashCode = new FletchFunctionBuilder.accessor(
481 functions.length, 483 functions.length,
482 false); 484 false);
483 functions.add(hashCode); 485 functions.add(hashCode);
484 486
485 int hashCodeSelector = FletchSelector.encodeGetter( 487 int hashCodeSelector = FletchSelector.encodeGetter(
486 context.getSymbolId("hashCode")); 488 context.getSymbolId("hashCode"));
487 int xorSelector = FletchSelector.encodeMethod( 489 int xorSelector = FletchSelector.encodeMethod(
488 context.getSymbolId("^"), 1); 490 context.getSymbolId("^"), 1);
489 hashCode.builder 491 hashCode.builder
490 ..loadParameter(0) 492 ..loadParameter(0)
491 ..loadField(0) 493 ..loadField(0)
492 ..invokeMethod(hashCodeSelector, 0) 494 ..invokeMethod(hashCodeSelector, 0)
493 ..loadLiteral(function.methodId) 495 ..loadLiteral(function.methodId)
494 ..invokeMethod(xorSelector, 1) 496 ..invokeMethod(xorSelector, 1)
495 ..ret() 497 ..ret()
496 ..methodEnd(); 498 ..methodEnd();
497 499
498 compiledClass.addToMethodTable(hashCodeSelector, hashCode); 500 classBuilder.addToMethodTable(hashCodeSelector, hashCode);
499 } 501 }
500 return compiledClass; 502 return classBuilder;
501 }); 503 });
502 } 504 }
503 505
504 CompiledFunction createCompiledFunction(FunctionElement function) { 506 FletchFunctionBuilder createFletchFunctionBuilder(FunctionElement function) {
505 assert(function.memberContext == function); 507 assert(function.memberContext == function);
506 508
507 CompiledClass holderClass; 509 FletchClassBuilder holderClass;
508 if (function.isInstanceMember || function.isGenerativeConstructor) { 510 if (function.isInstanceMember || function.isGenerativeConstructor) {
509 ClassElement enclosingClass = function.enclosingClass.declaration; 511 ClassElement enclosingClass = function.enclosingClass.declaration;
510 holderClass = registerClassElement(enclosingClass); 512 holderClass = registerClassElement(enclosingClass);
511 } 513 }
512 return internalCreateCompiledFunction( 514 return internalCreateFletchFunctionBuilder(
513 function, 515 function,
514 function.name, 516 function.name,
515 holderClass); 517 holderClass);
516 } 518 }
517 519
518 CompiledFunction internalCreateCompiledFunction( 520 FletchFunctionBuilder internalCreateFletchFunctionBuilder(
519 FunctionElement function, 521 FunctionElement function,
520 String name, 522 String name,
521 CompiledClass holderClass) { 523 FletchClassBuilder holderClass) {
522 return compiledFunctions.putIfAbsent(function.declaration, () { 524 return functionBuilders.putIfAbsent(function.declaration, () {
523 FunctionTypedElement implementation = function.implementation; 525 FunctionTypedElement implementation = function.implementation;
524 CompiledFunction compiledFunction = new CompiledFunction( 526 FletchFunctionBuilder functionBuilder = new FletchFunctionBuilder(
525 functions.length, 527 functions.length,
526 name, 528 name,
527 function, 529 function,
528 // Parameter initializers are expressed in the potential 530 // Parameter initializers are expressed in the potential
529 // implementation. 531 // implementation.
530 implementation.functionSignature, 532 implementation.functionSignature,
531 holderClass, 533 holderClass,
532 kind: function.isAccessor 534 kind: function.isAccessor
533 ? CompiledFunctionKind.ACCESSOR 535 ? FletchFunctionBuilderKind.ACCESSOR
534 : CompiledFunctionKind.NORMAL); 536 : FletchFunctionBuilderKind.NORMAL);
535 functions.add(compiledFunction); 537 functions.add(functionBuilder);
536 return compiledFunction; 538 return functionBuilder;
537 }); 539 });
538 } 540 }
539 541
540 int functionMethodId(FunctionElement function) { 542 int functionMethodId(FunctionElement function) {
541 return createCompiledFunction(function).methodId; 543 return createFletchFunctionBuilder(function).methodId;
542 } 544 }
543 545
544 CompiledFunction compiledFunctionFromTearoffClass(CompiledClass klass) { 546 FletchFunctionBuilder functionBuilderFromTearoffClass(
547 FletchClassBuilder klass) {
545 if (tearoffFunctions == null) { 548 if (tearoffFunctions == null) {
546 tearoffFunctions = <CompiledClass, CompiledFunction>{}; 549 tearoffFunctions = <FletchClassBuilder, FletchFunctionBuilder>{};
547 tearoffClasses.forEach((k, v) => tearoffFunctions[v] = k); 550 tearoffClasses.forEach((k, v) => tearoffFunctions[v] = k);
548 } 551 }
549 return tearoffFunctions[klass]; 552 return tearoffFunctions[klass];
550 } 553 }
551 554
552 void ensureDebugInfo(CompiledFunction function) { 555 void ensureDebugInfo(FletchFunctionBuilder function) {
553 if (function.debugInfo != null) return; 556 if (function.debugInfo != null) return;
554 function.debugInfo = new DebugInfo(function); 557 function.debugInfo = new DebugInfo(function);
555 AstElement element = function.element; 558 AstElement element = function.element;
556 if (element == null) return; 559 if (element == null) return;
557 List<Bytecode> expectedBytecodes = function.builder.bytecodes; 560 List<Bytecode> expectedBytecodes = function.builder.bytecodes;
558 element = element.implementation; 561 element = element.implementation;
559 TreeElements elements = element.resolvedAst.elements; 562 TreeElements elements = element.resolvedAst.elements;
560 ClosureEnvironment closureEnvironment = createClosureEnvironment( 563 ClosureEnvironment closureEnvironment = createClosureEnvironment(
561 element, 564 element,
562 elements); 565 elements);
563 CodegenVisitor codegen; 566 CodegenVisitor codegen;
564 if (function.isLazyFieldInitializer) { 567 if (function.isLazyFieldInitializer) {
565 codegen = new DebugInfoLazyFieldInitializerCodegen( 568 codegen = new DebugInfoLazyFieldInitializerCodegen(
566 function, 569 function,
567 context, 570 context,
568 elements, 571 elements,
569 null, 572 null,
570 closureEnvironment, 573 closureEnvironment,
571 element, 574 element,
572 compiler); 575 compiler);
573 } else if (function.isInitializerList) { 576 } else if (function.isInitializerList) {
574 ClassElement enclosingClass = element.enclosingClass; 577 ClassElement enclosingClass = element.enclosingClass;
575 CompiledClass compiledClass = compiledClasses[enclosingClass]; 578 FletchClassBuilder classBuilder = classBuilders[enclosingClass];
576 codegen = new DebugInfoConstructorCodegen( 579 codegen = new DebugInfoConstructorCodegen(
577 function, 580 function,
578 context, 581 context,
579 elements, 582 elements,
580 null, 583 null,
581 closureEnvironment, 584 closureEnvironment,
582 element, 585 element,
583 compiledClass, 586 classBuilder,
584 compiler); 587 compiler);
585 } else { 588 } else {
586 codegen = new DebugInfoFunctionCodegen( 589 codegen = new DebugInfoFunctionCodegen(
587 function, 590 function,
588 context, 591 context,
589 elements, 592 elements,
590 null, 593 null,
591 closureEnvironment, 594 closureEnvironment,
592 element, 595 element,
593 compiler); 596 compiler);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 void codegenFunction( 639 void codegenFunction(
637 FunctionElement function, 640 FunctionElement function,
638 TreeElements elements, 641 TreeElements elements,
639 Registry registry) { 642 Registry registry) {
640 registry.registerStaticInvocation(fletchSystemEntry); 643 registry.registerStaticInvocation(fletchSystemEntry);
641 644
642 ClosureEnvironment closureEnvironment = createClosureEnvironment( 645 ClosureEnvironment closureEnvironment = createClosureEnvironment(
643 function, 646 function,
644 elements); 647 elements);
645 648
646 CompiledFunction compiledFunction; 649 FletchFunctionBuilder functionBuilder;
647 650
648 if (function.memberContext != function) { 651 if (function.memberContext != function) {
649 compiledFunction = internalCreateCompiledFunction( 652 functionBuilder = internalCreateFletchFunctionBuilder(
650 function, 653 function,
651 Compiler.CALL_OPERATOR_NAME, 654 Compiler.CALL_OPERATOR_NAME,
652 createClosureClass(function, closureEnvironment)); 655 createClosureClass(function, closureEnvironment));
653 } else { 656 } else {
654 compiledFunction = createCompiledFunction(function); 657 functionBuilder = createFletchFunctionBuilder(function);
655 } 658 }
656 659
657 FunctionCodegen codegen = new FunctionCodegen( 660 FunctionCodegen codegen = new FunctionCodegen(
658 compiledFunction, 661 functionBuilder,
659 context, 662 context,
660 elements, 663 elements,
661 registry, 664 registry,
662 closureEnvironment, 665 closureEnvironment,
663 function); 666 function);
664 667
665 if (isNative(function)) { 668 if (isNative(function)) {
666 codegenNativeFunction(function, codegen); 669 codegenNativeFunction(function, codegen);
667 } else if (isExternal(function)) { 670 } else if (isExternal(function)) {
668 codegenExternalFunction(function, codegen); 671 codegenExternalFunction(function, codegen);
669 } else { 672 } else {
670 codegen.compile(); 673 codegen.compile();
671 } 674 }
672 675
673 // TODO(ahe): Don't do this. 676 // TODO(ahe): Don't do this.
674 compiler.enqueuer.codegen.generatedCode[function.declaration] = null; 677 compiler.enqueuer.codegen.generatedCode[function.declaration] = null;
675 678
676 if (compiledFunction.memberOf != null && 679 if (functionBuilder.memberOf != null &&
677 !function.isGenerativeConstructor) { 680 !function.isGenerativeConstructor) {
678 // Inject the function into the method table of the 'holderClass' class. 681 // Inject the function into the method table of the 'holderClass' class.
679 // Note that while constructor bodies has a this argument, we don't inject 682 // Note that while constructor bodies has a this argument, we don't inject
680 // them into the method table. 683 // them into the method table.
681 String symbol = context.getSymbolForFunction( 684 String symbol = context.getSymbolForFunction(
682 compiledFunction.name, 685 functionBuilder.name,
683 function.functionSignature, 686 function.functionSignature,
684 function.library); 687 function.library);
685 int id = context.getSymbolId(symbol); 688 int id = context.getSymbolId(symbol);
686 int arity = function.functionSignature.parameterCount; 689 int arity = function.functionSignature.parameterCount;
687 SelectorKind kind = SelectorKind.Method; 690 SelectorKind kind = SelectorKind.Method;
688 if (function.isGetter) kind = SelectorKind.Getter; 691 if (function.isGetter) kind = SelectorKind.Getter;
689 if (function.isSetter) kind = SelectorKind.Setter; 692 if (function.isSetter) kind = SelectorKind.Setter;
690 int fletchSelector = FletchSelector.encode(id, kind, arity); 693 int fletchSelector = FletchSelector.encode(id, kind, arity);
691 int methodId = compiledFunction.methodId; 694 int methodId = functionBuilder.methodId;
692 compiledFunction.memberOf.addToMethodTable( 695 functionBuilder.memberOf.addToMethodTable(
693 fletchSelector, compiledFunction); 696 fletchSelector, functionBuilder);
694 // Inject method into all mixin usages. 697 // Inject method into all mixin usages.
695 Iterable<ClassElement> mixinUsage = 698 Iterable<ClassElement> mixinUsage =
696 compiler.world.mixinUsesOf(function.enclosingClass); 699 compiler.world.mixinUsesOf(function.enclosingClass);
697 for (ClassElement usage in mixinUsage) { 700 for (ClassElement usage in mixinUsage) {
698 // TODO(ajohnsen): Consider having multiple 'memberOf' in 701 // TODO(ajohnsen): Consider having multiple 'memberOf' in
699 // CompiledFunction, to avoid duplicates. 702 // FletchFunctionBuilder, to avoid duplicates.
700 // Create a copy with a unique 'memberOf', so we can detect missing 703 // Create a copy with a unique 'memberOf', so we can detect missing
701 // stubs for the mixin applications as well. 704 // stubs for the mixin applications as well.
702 CompiledClass compiledUsage = registerClassElement(usage); 705 FletchClassBuilder compiledUsage = registerClassElement(usage);
703 FunctionTypedElement implementation = function.implementation; 706 FunctionTypedElement implementation = function.implementation;
704 CompiledFunction copy = new CompiledFunction( 707 FletchFunctionBuilder copy = new FletchFunctionBuilder(
705 functions.length, 708 functions.length,
706 function.name, 709 function.name,
707 implementation, 710 implementation,
708 implementation.functionSignature, 711 implementation.functionSignature,
709 compiledUsage, 712 compiledUsage,
710 kind: function.isAccessor 713 kind: function.isAccessor
711 ? CompiledFunctionKind.ACCESSOR 714 ? FletchFunctionBuilderKind.ACCESSOR
712 : CompiledFunctionKind.NORMAL); 715 : FletchFunctionBuilderKind.NORMAL);
713 functions.add(copy); 716 functions.add(copy);
714 compiledUsage.addToMethodTable(fletchSelector, copy); 717 compiledUsage.addToMethodTable(fletchSelector, copy);
715 copy.copyFrom(compiledFunction); 718 copy.copyFrom(functionBuilder);
716 } 719 }
717 } 720 }
718 721
719 if (compiler.verbose) { 722 if (compiler.verbose) {
720 compiler.log(compiledFunction.verboseToString()); 723 compiler.log(functionBuilder.verboseToString());
721 } 724 }
722 } 725 }
723 726
724 void codegenNativeFunction( 727 void codegenNativeFunction(
725 FunctionElement function, 728 FunctionElement function,
726 FunctionCodegen codegen) { 729 FunctionCodegen codegen) {
727 String name = '.${function.name}'; 730 String name = '.${function.name}';
728 731
729 ClassElement enclosingClass = function.enclosingClass; 732 ClassElement enclosingClass = function.enclosingClass;
730 if (enclosingClass != null) name = '${enclosingClass.name}$name'; 733 if (enclosingClass != null) name = '${enclosingClass.name}$name';
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 MemberElement member = element.memberContext; 854 MemberElement member = element.memberContext;
852 return closureEnvironments.putIfAbsent(member, () { 855 return closureEnvironments.putIfAbsent(member, () {
853 ClosureVisitor environment = new ClosureVisitor(member, elements); 856 ClosureVisitor environment = new ClosureVisitor(member, elements);
854 return environment.compute(); 857 return environment.compute();
855 }); 858 });
856 } 859 }
857 860
858 void createParameterMatchingStubs() { 861 void createParameterMatchingStubs() {
859 int length = functions.length; 862 int length = functions.length;
860 for (int i = 0; i < length; i++) { 863 for (int i = 0; i < length; i++) {
861 CompiledFunction function = functions[i]; 864 FletchFunctionBuilder function = functions[i];
862 if (!function.hasThisArgument || function.isAccessor) continue; 865 if (!function.hasThisArgument || function.isAccessor) continue;
863 String name = function.name; 866 String name = function.name;
864 Set<Selector> usage = compiler.resolverWorld.invokedNames[name]; 867 Set<Selector> usage = compiler.resolverWorld.invokedNames[name];
865 if (usage == null) continue; 868 if (usage == null) continue;
866 for (Selector use in usage) { 869 for (Selector use in usage) {
867 // TODO(ajohnsen): Somehow filter out private selectors of other 870 // TODO(ajohnsen): Somehow filter out private selectors of other
868 // libraries. 871 // libraries.
869 if (function.canBeCalledAs(use) && 872 if (function.canBeCalledAs(use) &&
870 !function.matchesSelector(use)) { 873 !function.matchesSelector(use)) {
871 function.createParameterMappingFor(use, context); 874 function.createParameterMappingFor(use, context);
872 } 875 }
873 } 876 }
874 } 877 }
875 } 878 }
876 879
877 void createTearoffStubs() { 880 void createTearoffStubs() {
878 int length = functions.length; 881 int length = functions.length;
879 for (int i = 0; i < length; i++) { 882 for (int i = 0; i < length; i++) {
880 CompiledFunction function = functions[i]; 883 FletchFunctionBuilder function = functions[i];
881 if (!function.hasThisArgument || function.isAccessor) continue; 884 if (!function.hasThisArgument || function.isAccessor) continue;
882 String name = function.name; 885 String name = function.name;
883 if (compiler.resolverWorld.invokedGetters.containsKey(name)) { 886 if (compiler.resolverWorld.invokedGetters.containsKey(name)) {
884 createTearoffGetterForFunction(function); 887 createTearoffGetterForFunction(function);
885 } 888 }
886 } 889 }
887 } 890 }
888 891
889 void createTearoffGetterForFunction(CompiledFunction function) { 892 void createTearoffGetterForFunction(FletchFunctionBuilder function) {
890 CompiledClass tearoffClass = createTearoffClass(function); 893 FletchClassBuilder tearoffClass = createTearoffClass(function);
891 CompiledFunction getter = new CompiledFunction.accessor( 894 FletchFunctionBuilder getter = new FletchFunctionBuilder.accessor(
892 functions.length, 895 functions.length,
893 false); 896 false);
894 functions.add(getter); 897 functions.add(getter);
895 int constId = getter.allocateConstantFromClass(tearoffClass.id); 898 int constId = getter.allocateConstantFromClass(tearoffClass.id);
896 getter.builder 899 getter.builder
897 ..loadParameter(0) 900 ..loadParameter(0)
898 ..allocate(constId, tearoffClass.fields) 901 ..allocate(constId, tearoffClass.fields)
899 ..ret() 902 ..ret()
900 ..methodEnd(); 903 ..methodEnd();
901 // If the name is private, we need the library. 904 // If the name is private, we need the library.
902 // Invariant: We only generate public stubs, e.g. 'call'. 905 // Invariant: We only generate public stubs, e.g. 'call'.
903 LibraryElement library; 906 LibraryElement library;
904 if (function.memberOf.element != null) { 907 if (function.memberOf.element != null) {
905 library = function.memberOf.element.library; 908 library = function.memberOf.element.library;
906 } 909 }
907 int fletchSelector = context.toFletchSelector( 910 int fletchSelector = context.toFletchSelector(
908 new Selector.getter(function.name, library)); 911 new Selector.getter(function.name, library));
909 function.memberOf.addToMethodTable(fletchSelector, getter); 912 function.memberOf.addToMethodTable(fletchSelector, getter);
910 } 913 }
911 914
912 int assembleProgram() { 915 int assembleProgram() {
913 createTearoffStubs(); 916 createTearoffStubs();
914 createParameterMatchingStubs(); 917 createParameterMatchingStubs();
915 918
916 for (CompiledClass compiledClass in classes) { 919 for (FletchClassBuilder classBuilder in classes) {
917 compiledClass.createIsEntries(this); 920 classBuilder.createIsEntries(this);
918 // TODO(ajohnsen): Currently, the CodegenRegistry does not enqueue fields. 921 // TODO(ajohnsen): Currently, the CodegenRegistry does not enqueue fields.
919 // This is a workaround, where we basically add getters for all fields. 922 // This is a workaround, where we basically add getters for all fields.
920 compiledClass.createImplicitAccessors(this); 923 classBuilder.createImplicitAccessors(this);
921 } 924 }
922 925
923 List<Command> commands = <Command>[ 926 List<Command> commands = <Command>[
924 const NewMap(MapId.methods), 927 const NewMap(MapId.methods),
925 const NewMap(MapId.classes), 928 const NewMap(MapId.classes),
926 const NewMap(MapId.constants), 929 const NewMap(MapId.constants),
927 ]; 930 ];
928 931
929 List<Function> deferredActions = <Function>[]; 932 List<Function> deferredActions = <Function>[];
930 933
931 functions.forEach((f) => pushNewFunction(f, commands, deferredActions)); 934 functions.forEach((f) => pushNewFunction(f, commands, deferredActions));
932 935
933 int changes = 0; 936 int changes = 0;
934 937
935 for (CompiledClass compiledClass in classes) { 938 for (FletchClassBuilder classBuilder in classes) {
936 ClassElement element = compiledClass.element; 939 ClassElement element = classBuilder.element;
937 if (builtinClasses.contains(element)) { 940 if (builtinClasses.contains(element)) {
938 int nameId = context.getSymbolId(element.name); 941 int nameId = context.getSymbolId(element.name);
939 commands.add(new PushBuiltinClass(nameId, compiledClass.fields)); 942 commands.add(new PushBuiltinClass(nameId, classBuilder.fields));
940 } else { 943 } else {
941 commands.add(new PushNewClass(compiledClass.fields)); 944 commands.add(new PushNewClass(classBuilder.fields));
942 } 945 }
943 946
944 commands.add(const Dup()); 947 commands.add(const Dup());
945 commands.add(new PopToMap(MapId.classes, compiledClass.id)); 948 commands.add(new PopToMap(MapId.classes, classBuilder.id));
946 949
947 Map<int, int> methodTable = compiledClass.computeMethodTable(this); 950 Map<int, int> methodTable = classBuilder.computeMethodTable(this);
948 methodTable.forEach((int selector, int methodId) { 951 methodTable.forEach((int selector, int methodId) {
949 commands.add(new PushNewInteger(selector)); 952 commands.add(new PushNewInteger(selector));
950 commands.add(new PushFromMap(MapId.methods, methodId)); 953 commands.add(new PushFromMap(MapId.methods, methodId));
951 }); 954 });
952 commands.add(new ChangeMethodTable(methodTable.length)); 955 commands.add(new ChangeMethodTable(methodTable.length));
953 956
954 changes++; 957 changes++;
955 } 958 }
956 959
957 context.forEachStatic((element, index) { 960 context.forEachStatic((element, index) {
958 CompiledFunction initializer = lazyFieldInitializers[element]; 961 FletchFunctionBuilder initializer = lazyFieldInitializers[element];
959 if (initializer != null) { 962 if (initializer != null) {
960 commands.add(new PushFromMap(MapId.methods, initializer.methodId)); 963 commands.add(new PushFromMap(MapId.methods, initializer.methodId));
961 commands.add(const PushNewInitializer()); 964 commands.add(const PushNewInitializer());
962 } else { 965 } else {
963 commands.add(const PushNull()); 966 commands.add(const PushNull());
964 } 967 }
965 }); 968 });
966 commands.add(new ChangeStatics(context.staticIndices.length)); 969 commands.add(new ChangeStatics(context.staticIndices.length));
967 changes++; 970 changes++;
968 971
(...skipping 23 matching lines...) Expand all
992 ListConstantValue value = constant; 995 ListConstantValue value = constant;
993 addList(constant.entries); 996 addList(constant.entries);
994 } else if (constant.isMap) { 997 } else if (constant.isMap) {
995 MapConstantValue value = constant; 998 MapConstantValue value = constant;
996 addList(value.keys); 999 addList(value.keys);
997 addList(value.values); 1000 addList(value.values);
998 commands.add(new PushConstantMap(value.length * 2)); 1001 commands.add(new PushConstantMap(value.length * 2));
999 } else if (constant.isConstructedObject) { 1002 } else if (constant.isConstructedObject) {
1000 ConstructedConstantValue value = constant; 1003 ConstructedConstantValue value = constant;
1001 ClassElement classElement = value.type.element; 1004 ClassElement classElement = value.type.element;
1002 CompiledClass compiledClass = compiledClasses[classElement]; 1005 FletchClassBuilder classBuilder = classBuilders[classElement];
1003 for (ConstantValue field in value.fields.values) { 1006 for (ConstantValue field in value.fields.values) {
1004 int fieldId = context.compiledConstants[field]; 1007 int fieldId = context.compiledConstants[field];
1005 commands.add(new PushFromMap(MapId.constants, fieldId)); 1008 commands.add(new PushFromMap(MapId.constants, fieldId));
1006 } 1009 }
1007 commands 1010 commands
1008 ..add(new PushFromMap(MapId.classes, compiledClass.id)) 1011 ..add(new PushFromMap(MapId.classes, classBuilder.id))
1009 ..add(const PushNewInstance()); 1012 ..add(const PushNewInstance());
1010 } else if (constant is FletchClassInstanceConstant) { 1013 } else if (constant is FletchClassInstanceConstant) {
1011 commands 1014 commands
1012 ..add(new PushFromMap(MapId.classes, constant.classId)) 1015 ..add(new PushFromMap(MapId.classes, constant.classId))
1013 ..add(const PushNewInstance()); 1016 ..add(const PushNewInstance());
1014 } else { 1017 } else {
1015 throw "Unsupported constant: ${constant.toStructuredString()}"; 1018 throw "Unsupported constant: ${constant.toStructuredString()}";
1016 } 1019 }
1017 commands.add(new PopToMap(MapId.constants, id)); 1020 commands.add(new PopToMap(MapId.constants, id));
1018 }); 1021 });
1019 1022
1020 for (CompiledClass compiledClass in classes) { 1023 for (FletchClassBuilder classBuilder in classes) {
1021 CompiledClass superclass = compiledClass.superclass; 1024 FletchClassBuilder superclass = classBuilder.superclass;
1022 if (superclass == null) continue; 1025 if (superclass == null) continue;
1023 commands.add(new PushFromMap(MapId.classes, compiledClass.id)); 1026 commands.add(new PushFromMap(MapId.classes, classBuilder.id));
1024 commands.add(new PushFromMap(MapId.classes, superclass.id)); 1027 commands.add(new PushFromMap(MapId.classes, superclass.id));
1025 commands.add(const ChangeSuperClass()); 1028 commands.add(const ChangeSuperClass());
1026 changes++; 1029 changes++;
1027 } 1030 }
1028 1031
1029 for (Function action in deferredActions) { 1032 for (Function action in deferredActions) {
1030 action(); 1033 action();
1031 changes++; 1034 changes++;
1032 } 1035 }
1033 1036
1034 commands.add(new CommitChanges(changes)); 1037 commands.add(new CommitChanges(changes));
1035 1038
1036 commands.add(const PushNewInteger(0)); 1039 commands.add(const PushNewInteger(0));
1037 1040
1038 commands.add(new PushFromMap( 1041 commands.add(new PushFromMap(
1039 MapId.methods, 1042 MapId.methods,
1040 compiledFunctions[fletchSystemEntry].methodId)); 1043 functionBuilders[fletchSystemEntry].methodId));
1041 1044
1042 this.commands = commands; 1045 this.commands = commands;
1043 1046
1044 return 0; 1047 return 0;
1045 } 1048 }
1046 1049
1047 void pushNewFunction( 1050 void pushNewFunction(
1048 CompiledFunction compiledFunction, 1051 FletchFunctionBuilder functionBuilder,
1049 List<Command> commands, 1052 List<Command> commands,
1050 List<Function> deferredActions) { 1053 List<Function> deferredActions) {
1051 int arity = compiledFunction.builder.functionArity; 1054 int arity = functionBuilder.builder.functionArity;
1052 int constantCount = compiledFunction.constants.length; 1055 int constantCount = functionBuilder.constants.length;
1053 int methodId = compiledFunction.methodId; 1056 int methodId = functionBuilder.methodId;
1054 1057
1055 assert(functions[methodId] == compiledFunction); 1058 assert(functions[methodId] == functionBuilder);
1056 assert(compiledFunction.builder.bytecodes.isNotEmpty); 1059 assert(functionBuilder.builder.bytecodes.isNotEmpty);
1057 1060
1058 compiledFunction.constants.forEach((constant, int index) { 1061 functionBuilder.constants.forEach((constant, int index) {
1059 if (constant is ConstantValue) { 1062 if (constant is ConstantValue) {
1060 if (constant is FletchFunctionConstant) { 1063 if (constant is FletchFunctionConstant) {
1061 commands.add(const PushNull()); 1064 commands.add(const PushNull());
1062 deferredActions.add(() { 1065 deferredActions.add(() {
1063 commands 1066 commands
1064 ..add(new PushFromMap(MapId.methods, methodId)) 1067 ..add(new PushFromMap(MapId.methods, methodId))
1065 ..add(new PushFromMap(MapId.methods, constant.methodId)) 1068 ..add(new PushFromMap(MapId.methods, constant.methodId))
1066 ..add(new ChangeMethodLiteral(index)); 1069 ..add(new ChangeMethodLiteral(index));
1067 }); 1070 });
1068 } else if (constant is FletchClassConstant) { 1071 } else if (constant is FletchClassConstant) {
(...skipping 19 matching lines...) Expand all
1088 } 1091 }
1089 } else { 1092 } else {
1090 throw "Unsupported constant: ${constant.runtimeType}"; 1093 throw "Unsupported constant: ${constant.runtimeType}";
1091 } 1094 }
1092 }); 1095 });
1093 1096
1094 commands.add( 1097 commands.add(
1095 new PushNewFunction( 1098 new PushNewFunction(
1096 arity, 1099 arity,
1097 constantCount, 1100 constantCount,
1098 compiledFunction.builder.bytecodes, 1101 functionBuilder.builder.bytecodes,
1099 compiledFunction.builder.catchRanges)); 1102 functionBuilder.builder.catchRanges));
1100 1103
1101 commands.add(new PopToMap(MapId.methods, methodId)); 1104 commands.add(new PopToMap(MapId.methods, methodId));
1102 } 1105 }
1103 1106
1104 bool registerDeferredLoading(Spannable node, Registry registry) { 1107 bool registerDeferredLoading(Spannable node, Registry registry) {
1105 compiler.reportWarning( 1108 compiler.reportWarning(
1106 node, 1109 node,
1107 MessageKind.GENERIC, 1110 MessageKind.GENERIC,
1108 {'text': "Deferred loading is not supported."}); 1111 {'text': "Deferred loading is not supported."});
1109 return false; 1112 return false;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 return element; 1185 return element;
1183 } 1186 }
1184 1187
1185 int compileLazyFieldInitializer(FieldElement field, Registry registry) { 1188 int compileLazyFieldInitializer(FieldElement field, Registry registry) {
1186 int index = context.getStaticFieldIndex(field, null); 1189 int index = context.getStaticFieldIndex(field, null);
1187 1190
1188 if (field.initializer == null) return index; 1191 if (field.initializer == null) return index;
1189 1192
1190 if (lazyFieldInitializers.containsKey(field)) return index; 1193 if (lazyFieldInitializers.containsKey(field)) return index;
1191 1194
1192 CompiledFunction compiledFunction = new CompiledFunction.lazyInit( 1195 FletchFunctionBuilder functionBuilder = new FletchFunctionBuilder.lazyInit(
1193 functions.length, 1196 functions.length,
1194 "${field.name} lazy initializer", 1197 "${field.name} lazy initializer",
1195 field, 1198 field,
1196 0); 1199 0);
1197 functions.add(compiledFunction); 1200 functions.add(functionBuilder);
1198 lazyFieldInitializers[field] = compiledFunction; 1201 lazyFieldInitializers[field] = functionBuilder;
1199 1202
1200 TreeElements elements = field.resolvedAst.elements; 1203 TreeElements elements = field.resolvedAst.elements;
1201 1204
1202 ClosureEnvironment closureEnvironment = createClosureEnvironment( 1205 ClosureEnvironment closureEnvironment = createClosureEnvironment(
1203 field, 1206 field,
1204 elements); 1207 elements);
1205 1208
1206 LazyFieldInitializerCodegen codegen = new LazyFieldInitializerCodegen( 1209 LazyFieldInitializerCodegen codegen = new LazyFieldInitializerCodegen(
1207 compiledFunction, 1210 functionBuilder,
1208 context, 1211 context,
1209 elements, 1212 elements,
1210 registry, 1213 registry,
1211 closureEnvironment, 1214 closureEnvironment,
1212 field); 1215 field);
1213 1216
1214 codegen.compile(); 1217 codegen.compile();
1215 1218
1216 return index; 1219 return index;
1217 } 1220 }
1218 1221
1219 CompiledFunction compileConstructor(ConstructorElement constructor, 1222 FletchFunctionBuilder compileConstructor(ConstructorElement constructor,
1220 Registry registry) { 1223 Registry registry) {
1221 assert(constructor.isDeclaration); 1224 assert(constructor.isDeclaration);
1222 CompiledFunction compiledFunction = constructors[constructor]; 1225 FletchFunctionBuilder functionBuilder = constructors[constructor];
1223 if (compiledFunction != null) return compiledFunction; 1226 if (functionBuilder != null) return functionBuilder;
1224 1227
1225 ClassElement classElement = constructor.enclosingClass; 1228 ClassElement classElement = constructor.enclosingClass;
1226 CompiledClass compiledClass = registerClassElement(classElement); 1229 FletchClassBuilder classBuilder = registerClassElement(classElement);
1227 1230
1228 ConstructorElement implementation = constructor.implementation; 1231 ConstructorElement implementation = constructor.implementation;
1229 1232
1230 if (compiler.verbose) { 1233 if (compiler.verbose) {
1231 // TODO(johnniwinther): Use reportVerboseInfo once added. 1234 // TODO(johnniwinther): Use reportVerboseInfo once added.
1232 compiler.reportHint( 1235 compiler.reportHint(
1233 constructor, 1236 constructor,
1234 MessageKind.GENERIC, 1237 MessageKind.GENERIC,
1235 {'text': 'Compiling constructor ${implementation.name}'}); 1238 {'text': 'Compiling constructor ${implementation.name}'});
1236 } 1239 }
1237 1240
1238 TreeElements elements = implementation.resolvedAst.elements; 1241 TreeElements elements = implementation.resolvedAst.elements;
1239 1242
1240 ClosureEnvironment closureEnvironment = createClosureEnvironment( 1243 ClosureEnvironment closureEnvironment = createClosureEnvironment(
1241 implementation, 1244 implementation,
1242 elements); 1245 elements);
1243 1246
1244 compiledFunction = new CompiledFunction( 1247 functionBuilder = new FletchFunctionBuilder(
1245 functions.length, 1248 functions.length,
1246 implementation.name, 1249 implementation.name,
1247 implementation, 1250 implementation,
1248 implementation.functionSignature, 1251 implementation.functionSignature,
1249 null, 1252 null,
1250 kind: CompiledFunctionKind.INITIALIZER_LIST); 1253 kind: FletchFunctionBuilderKind.INITIALIZER_LIST);
1251 functions.add(compiledFunction); 1254 functions.add(functionBuilder);
1252 constructors[constructor] = compiledFunction; 1255 constructors[constructor] = functionBuilder;
1253 1256
1254 ConstructorCodegen codegen = new ConstructorCodegen( 1257 ConstructorCodegen codegen = new ConstructorCodegen(
1255 compiledFunction, 1258 functionBuilder,
1256 context, 1259 context,
1257 elements, 1260 elements,
1258 registry, 1261 registry,
1259 closureEnvironment, 1262 closureEnvironment,
1260 implementation, 1263 implementation,
1261 compiledClass); 1264 classBuilder);
1262 1265
1263 codegen.compile(); 1266 codegen.compile();
1264 1267
1265 if (compiler.verbose) { 1268 if (compiler.verbose) {
1266 compiler.log(compiledFunction.verboseToString()); 1269 compiler.log(functionBuilder.verboseToString());
1267 } 1270 }
1268 1271
1269 return compiledFunction; 1272 return functionBuilder;
1270 } 1273 }
1271 1274
1272 /** 1275 /**
1273 * Generate a getter for field [fieldIndex]. 1276 * Generate a getter for field [fieldIndex].
1274 */ 1277 */
1275 int makeGetter(int fieldIndex) { 1278 int makeGetter(int fieldIndex) {
1276 return getters.putIfAbsent(fieldIndex, () { 1279 return getters.putIfAbsent(fieldIndex, () {
1277 CompiledFunction stub = new CompiledFunction.accessor( 1280 FletchFunctionBuilder stub = new FletchFunctionBuilder.accessor(
1278 functions.length, 1281 functions.length,
1279 false); 1282 false);
1280 functions.add(stub); 1283 functions.add(stub);
1281 stub.builder 1284 stub.builder
1282 ..loadParameter(0) 1285 ..loadParameter(0)
1283 ..loadField(fieldIndex) 1286 ..loadField(fieldIndex)
1284 ..ret() 1287 ..ret()
1285 ..methodEnd(); 1288 ..methodEnd();
1286 return stub.methodId; 1289 return stub.methodId;
1287 }); 1290 });
1288 } 1291 }
1289 1292
1290 /** 1293 /**
1291 * Generate a setter for field [fieldIndex]. 1294 * Generate a setter for field [fieldIndex].
1292 */ 1295 */
1293 int makeSetter(int fieldIndex) { 1296 int makeSetter(int fieldIndex) {
1294 return setters.putIfAbsent(fieldIndex, () { 1297 return setters.putIfAbsent(fieldIndex, () {
1295 CompiledFunction stub = new CompiledFunction.accessor( 1298 FletchFunctionBuilder stub = new FletchFunctionBuilder.accessor(
1296 functions.length, 1299 functions.length,
1297 true); 1300 true);
1298 functions.add(stub); 1301 functions.add(stub);
1299 stub.builder 1302 stub.builder
1300 ..loadParameter(0) 1303 ..loadParameter(0)
1301 ..loadParameter(1) 1304 ..loadParameter(1)
1302 ..storeField(fieldIndex) 1305 ..storeField(fieldIndex)
1303 // Top is at this point the rhs argument, thus the return value. 1306 // Top is at this point the rhs argument, thus the return value.
1304 ..ret() 1307 ..ret()
1305 ..methodEnd(); 1308 ..methodEnd();
1306 return stub.methodId; 1309 return stub.methodId;
1307 }); 1310 });
1308 } 1311 }
1309 1312
1310 void generateUnimplementedError( 1313 void generateUnimplementedError(
1311 Spannable spannable, 1314 Spannable spannable,
1312 String reason, 1315 String reason,
1313 CompiledFunction function) { 1316 FletchFunctionBuilder function) {
1314 compiler.reportError( 1317 compiler.reportError(
1315 spannable, MessageKind.GENERIC, {'text': reason}); 1318 spannable, MessageKind.GENERIC, {'text': reason});
1316 var constString = constantSystem.createString( 1319 var constString = constantSystem.createString(
1317 new DartString.literal(reason)); 1320 new DartString.literal(reason));
1318 context.markConstantUsed(constString); 1321 context.markConstantUsed(constString);
1319 function 1322 function
1320 ..builder.loadConst(function.allocateConstant(constString)) 1323 ..builder.loadConst(function.allocateConstant(constString))
1321 ..builder.emitThrow(); 1324 ..builder.emitThrow();
1322 } 1325 }
1323 1326
1324 void forgetElement(Element element) { 1327 void forgetElement(Element element) {
1325 CompiledFunction compiledFunction = compiledFunctions[element]; 1328 FletchFunctionBuilder functionBuilder = functionBuilders[element];
1326 if (compiledFunction == null) return; 1329 if (functionBuilder == null) return;
1327 compiledFunction.reuse(); 1330 functionBuilder.reuse();
1328 } 1331 }
1329 } 1332 }
OLDNEW
« no previous file with comments | « pkg/fletchc/lib/src/debug_info_lazy_field_initializer_codegen.dart ('k') | pkg/fletchc/lib/src/fletch_class_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698