| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.js_emitter.program_builder; | 5 library dart2js.js_emitter.program_builder; |
| 6 | 6 |
| 7 import 'js_emitter.dart' show computeMixinClass; | 7 import 'js_emitter.dart' show computeMixinClass; |
| 8 import 'model.dart'; | 8 import 'model.dart'; |
| 9 | 9 |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 part 'registry.dart'; | 30 part 'registry.dart'; |
| 31 | 31 |
| 32 class ProgramBuilder { | 32 class ProgramBuilder { |
| 33 final Compiler _compiler; | 33 final Compiler _compiler; |
| 34 final Namer namer; | 34 final Namer namer; |
| 35 final emitterTask.CodeEmitterTask _task; | 35 final emitterTask.CodeEmitterTask _task; |
| 36 | 36 |
| 37 final Registry _registry; | 37 final Registry _registry; |
| 38 | 38 |
| 39 /// True if the program should store function types in the metadata. |
| 40 bool _storeFunctionTypesInMetadata = false; |
| 41 |
| 39 ProgramBuilder(Compiler compiler, | 42 ProgramBuilder(Compiler compiler, |
| 40 this.namer, | 43 this.namer, |
| 41 this._task) | 44 this._task) |
| 42 : this._compiler = compiler, | 45 : this._compiler = compiler, |
| 43 this._registry = new Registry(compiler); | 46 this._registry = new Registry(compiler); |
| 44 | 47 |
| 45 JavaScriptBackend get backend => _compiler.backend; | 48 JavaScriptBackend get backend => _compiler.backend; |
| 46 Universe get universe => _compiler.codegenWorld; | 49 Universe get universe => _compiler.codegenWorld; |
| 47 | 50 |
| 48 /// Mapping from [ClassElement] to constructed [Class]. We need this to | 51 /// Mapping from [ClassElement] to constructed [Class]. We need this to |
| 49 /// update the superclass in the [Class]. | 52 /// update the superclass in the [Class]. |
| 50 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; | 53 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; |
| 51 | 54 |
| 52 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to | 55 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to |
| 53 /// generate the deferredLoadingMap (to know which hunks to load). | 56 /// generate the deferredLoadingMap (to know which hunks to load). |
| 54 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; | 57 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; |
| 55 | 58 |
| 56 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to | 59 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to |
| 57 /// update field-initializers to point to the ConstantModel. | 60 /// update field-initializers to point to the ConstantModel. |
| 58 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{}; | 61 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{}; |
| 59 | 62 |
| 60 Program buildProgram() { | 63 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { |
| 64 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; |
| 61 // Note: In rare cases (mostly tests) output units can be empty. This | 65 // Note: In rare cases (mostly tests) output units can be empty. This |
| 62 // happens when the deferred code is dead-code eliminated but we still need | 66 // happens when the deferred code is dead-code eliminated but we still need |
| 63 // to check that the library has been loaded. | 67 // to check that the library has been loaded. |
| 64 _compiler.deferredLoadTask.allOutputUnits.forEach( | 68 _compiler.deferredLoadTask.allOutputUnits.forEach( |
| 65 _registry.registerOutputUnit); | 69 _registry.registerOutputUnit); |
| 66 _task.outputClassLists.forEach(_registry.registerElements); | 70 _task.outputClassLists.forEach(_registry.registerElements); |
| 67 _task.outputStaticLists.forEach(_registry.registerElements); | 71 _task.outputStaticLists.forEach(_registry.registerElements); |
| 68 _task.outputConstantLists.forEach(_registerConstants); | 72 _task.outputConstantLists.forEach(_registerConstants); |
| 69 _task.outputStaticNonFinalFieldLists.forEach(_registry.registerElements); | 73 _task.outputStaticNonFinalFieldLists.forEach(_registry.registerElements); |
| 70 | 74 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 | 281 |
| 278 // MixinApplications run through the members of their mixin. Here, we are | 282 // MixinApplications run through the members of their mixin. Here, we are |
| 279 // only interested in direct members. | 283 // only interested in direct members. |
| 280 if (!element.isMixinApplication) { | 284 if (!element.isMixinApplication) { |
| 281 implementation.forEachMember(visitMember, includeBackendMembers: true); | 285 implementation.forEachMember(visitMember, includeBackendMembers: true); |
| 282 } | 286 } |
| 283 | 287 |
| 284 emitterTask.TypeTestGenerator generator = | 288 emitterTask.TypeTestGenerator generator = |
| 285 new emitterTask.TypeTestGenerator(_compiler, _task, namer); | 289 new emitterTask.TypeTestGenerator(_compiler, _task, namer); |
| 286 emitterTask.TypeTestProperties typeTests = | 290 emitterTask.TypeTestProperties typeTests = |
| 287 generator.generateIsTests(element); | 291 generator.generateIsTests( |
| 292 element, |
| 293 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); |
| 288 | 294 |
| 289 // At this point a mixin application must not have any methods or fields. | 295 List<StubMethod> isChecks = <StubMethod>[]; |
| 290 // Type-tests might be added to mixin applications, too. | |
| 291 assert(!element.isMixinApplication || methods.isEmpty); | |
| 292 assert(!element.isMixinApplication || fields.isEmpty); | |
| 293 | |
| 294 // TODO(floitsch): we should not add the code here, but have a list of | |
| 295 // is/as classes in the Class object. | |
| 296 // The individual emitters should then call the type test generator to | |
| 297 // generate the code. | |
| 298 typeTests.properties.forEach((String name, js.Node code) { | 296 typeTests.properties.forEach((String name, js.Node code) { |
| 299 methods.add(_buildStubMethod(name, code)); | 297 isChecks.add(_buildStubMethod(name, code)); |
| 300 }); | 298 }); |
| 301 | 299 |
| 302 String name = namer.getNameOfClass(element); | 300 String name = namer.getNameOfClass(element); |
| 303 String holderName = namer.globalObjectFor(element); | 301 String holderName = namer.globalObjectFor(element); |
| 304 Holder holder = _registry.registerHolder(holderName); | 302 Holder holder = _registry.registerHolder(holderName); |
| 305 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element); | 303 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element); |
| 306 bool isInstantiated = | 304 bool isInstantiated = |
| 307 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); | 305 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); |
| 308 | 306 |
| 309 Class result; | 307 Class result; |
| 310 if (element.isMixinApplication && !onlyForRti) { | 308 if (element.isMixinApplication && !onlyForRti) { |
| 311 assert(!element.isNative); | 309 assert(!element.isNative); |
| 310 assert(methods.isEmpty); |
| 311 assert(fields.isEmpty); |
| 312 |
| 312 result = new MixinApplication(element, | 313 result = new MixinApplication(element, |
| 313 name, holder, methods, fields, | 314 name, holder, isChecks, |
| 315 typeTests.functionTypeIndex, |
| 314 isDirectlyInstantiated: isInstantiated, | 316 isDirectlyInstantiated: isInstantiated, |
| 315 onlyForRti: onlyForRti); | 317 onlyForRti: onlyForRti); |
| 316 } else { | 318 } else { |
| 317 result = new Class(element, | 319 result = new Class(element, |
| 318 name, holder, methods, fields, | 320 name, holder, methods, fields, isChecks, |
| 321 typeTests.functionTypeIndex, |
| 319 isDirectlyInstantiated: isInstantiated, | 322 isDirectlyInstantiated: isInstantiated, |
| 320 onlyForRti: onlyForRti, | 323 onlyForRti: onlyForRti, |
| 321 isNative: element.isNative); | 324 isNative: element.isNative); |
| 322 } | 325 } |
| 323 _classes[element] = result; | 326 _classes[element] = result; |
| 324 return result; | 327 return result; |
| 325 } | 328 } |
| 326 | 329 |
| 327 Method _buildMethod(FunctionElement element, js.Expression code) { | 330 Method _buildMethod(FunctionElement element, js.Expression code) { |
| 328 String name = namer.getNameOfInstanceMember(element); | 331 String name = namer.getNameOfInstanceMember(element); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 _registry.registerConstant(outputUnit, constantValue); | 460 _registry.registerConstant(outputUnit, constantValue); |
| 458 assert(!_constants.containsKey(constantValue)); | 461 assert(!_constants.containsKey(constantValue)); |
| 459 String name = namer.constantName(constantValue); | 462 String name = namer.constantName(constantValue); |
| 460 String constantObject = namer.globalObjectForConstant(constantValue); | 463 String constantObject = namer.globalObjectForConstant(constantValue); |
| 461 Holder holder = _registry.registerHolder(constantObject); | 464 Holder holder = _registry.registerHolder(constantObject); |
| 462 Constant constant = new Constant(name, holder, constantValue); | 465 Constant constant = new Constant(name, holder, constantValue); |
| 463 _constants[constantValue] = constant; | 466 _constants[constantValue] = constant; |
| 464 } | 467 } |
| 465 } | 468 } |
| 466 } | 469 } |
| OLD | NEW |