Index: pkg/compiler/lib/src/js_model/js_strategy.dart |
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart |
index a1aaef41b053c77dc5169f5c6737880660d1fe38..94215a63b5411dff60d47ba7fad2c12a71baa0f1 100644 |
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart |
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart |
@@ -9,8 +9,10 @@ import '../common.dart'; |
import '../common/tasks.dart'; |
import '../common_elements.dart'; |
import '../compiler.dart'; |
-import '../elements/elements.dart' show TypedefElement; |
+import '../constants/constant_system.dart'; |
+import '../elements/elements.dart' show ClassElement, TypedefElement; |
import '../elements/entities.dart'; |
+import '../elements/types.dart'; |
import '../enqueue.dart'; |
import '../io/source_information.dart'; |
import '../js_emitter/sorter.dart'; |
@@ -25,6 +27,7 @@ import '../kernel/element_map.dart'; |
import '../kernel/element_map_impl.dart'; |
import '../kernel/kernel_backend_strategy.dart'; |
import '../kernel/kernel_strategy.dart'; |
+import '../native/behavior.dart'; |
import '../ssa/ssa.dart'; |
import '../universe/class_set.dart'; |
import '../universe/world_builder.dart'; |
@@ -53,36 +56,168 @@ class JsBackendStrategy implements KernelBackendStrategy { |
GlobalLocalsMap get globalLocalsMapForTesting => _globalLocalsMap; |
+ BackendUsage _convertBackendUsage( |
+ JsToFrontendMap map, BackendUsageImpl backendUsage) { |
+ Set<FunctionEntity> globalFunctionDependencies = |
+ map.toBackendFunctionSet(backendUsage.globalFunctionDependencies); |
+ Set<ClassEntity> globalClassDependencies = |
+ map.toBackendClassSet(backendUsage.globalClassDependencies); |
+ Set<FunctionEntity> helperFunctionsUsed = |
+ map.toBackendFunctionSet(backendUsage.helperFunctionsUsed); |
+ Set<ClassEntity> helperClassesUsed = |
+ map.toBackendClassSet(backendUsage.helperClassesUsed); |
+ |
+ return new BackendUsageImpl( |
+ globalFunctionDependencies: globalFunctionDependencies, |
+ globalClassDependencies: globalClassDependencies, |
+ helperFunctionsUsed: helperFunctionsUsed, |
+ helperClassesUsed: helperClassesUsed, |
+ needToInitializeIsolateAffinityTag: |
+ backendUsage.needToInitializeIsolateAffinityTag, |
+ needToInitializeDispatchProperty: |
+ backendUsage.needToInitializeDispatchProperty, |
+ requiresPreamble: backendUsage.requiresPreamble, |
+ isInvokeOnUsed: backendUsage.isInvokeOnUsed, |
+ isRuntimeTypeUsed: backendUsage.isRuntimeTypeUsed, |
+ isIsolateInUse: backendUsage.isIsolateInUse, |
+ isFunctionApplyUsed: backendUsage.isFunctionApplyUsed, |
+ isMirrorsUsed: backendUsage.isMirrorsUsed, |
+ isNoSuchMethodUsed: backendUsage.isNoSuchMethodUsed); |
+ } |
+ |
+ NativeBasicData _convertNativeBasicData( |
+ JsToFrontendMap map, NativeBasicDataImpl nativeBasicData) { |
+ Map<ClassEntity, NativeClassTag> nativeClassTagInfo = |
+ <ClassEntity, NativeClassTag>{}; |
+ nativeBasicData.nativeClassTagInfo |
+ .forEach((ClassEntity cls, NativeClassTag tag) { |
+ nativeClassTagInfo[map.toBackendClass(cls)] = tag; |
+ }); |
+ Set<LibraryEntity> jsInteropLibraries = |
+ map.toBackendLibrarySet(nativeBasicData.jsInteropLibraries); |
+ Set<ClassEntity> jsInteropClasses = |
+ map.toBackendClassSet(nativeBasicData.jsInteropClasses); |
+ return new NativeBasicDataImpl(_elementEnvironment, nativeClassTagInfo, |
+ jsInteropLibraries, jsInteropClasses); |
+ } |
+ |
+ NativeData _convertNativeData( |
+ JsToFrontendMap map, NativeDataImpl nativeData) { |
+ convertNativeBehaviorType(type) { |
+ if (type is DartType) return map.toBackendType(type); |
+ assert(type is SpecialType); |
+ return type; |
+ } |
+ |
+ NativeBehavior convertNativeBehavior(NativeBehavior behavior) { |
+ NativeBehavior newBehavior = new NativeBehavior(); |
+ |
+ for (dynamic type in behavior.typesReturned) { |
+ newBehavior.typesReturned.add(convertNativeBehaviorType(type)); |
+ } |
+ for (dynamic type in behavior.typesInstantiated) { |
+ newBehavior.typesInstantiated.add(convertNativeBehaviorType(type)); |
+ } |
+ |
+ newBehavior.codeTemplateText = behavior.codeTemplateText; |
+ newBehavior.codeTemplate = behavior.codeTemplate; |
+ newBehavior.throwBehavior = behavior.throwBehavior; |
+ newBehavior.isAllocation = behavior.isAllocation; |
+ newBehavior.useGvn = behavior.useGvn; |
+ return newBehavior; |
+ } |
+ |
+ NativeBasicData nativeBasicData = _convertNativeBasicData(map, nativeData); |
+ |
+ Map<MemberEntity, String> nativeMemberName = |
+ map.toBackendMemberMap(nativeData.nativeMemberName, identity); |
+ Map<FunctionEntity, NativeBehavior> nativeMethodBehavior = |
+ <FunctionEntity, NativeBehavior>{}; |
+ nativeData.nativeMethodBehavior |
+ .forEach((FunctionEntity method, NativeBehavior behavior) { |
+ nativeMethodBehavior[map.toBackendMember(method)] = |
+ convertNativeBehavior(behavior); |
+ }); |
+ Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior = |
+ map.toBackendMemberMap( |
+ nativeData.nativeFieldLoadBehavior, convertNativeBehavior); |
+ Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior = |
+ map.toBackendMemberMap( |
+ nativeData.nativeFieldStoreBehavior, convertNativeBehavior); |
+ Map<LibraryEntity, String> jsInteropLibraryNames = |
+ map.toBackendLibraryMap(nativeData.jsInteropLibraryNames, identity); |
+ Set<ClassEntity> anonymousJsInteropClasses = |
+ map.toBackendClassSet(nativeData.anonymousJsInteropClasses); |
+ Map<ClassEntity, String> jsInteropClassNames = |
+ map.toBackendClassMap(nativeData.jsInteropClassNames, identity); |
+ Map<MemberEntity, String> jsInteropMemberNames = |
+ map.toBackendMemberMap(nativeData.jsInteropMemberNames, identity); |
+ |
+ return new NativeDataImpl( |
+ nativeBasicData, |
+ nativeMemberName, |
+ nativeMethodBehavior, |
+ nativeFieldLoadBehavior, |
+ nativeFieldStoreBehavior, |
+ jsInteropLibraryNames, |
+ anonymousJsInteropClasses, |
+ jsInteropClassNames, |
+ jsInteropMemberNames); |
+ } |
+ |
+ InterceptorData _convertInterceptorData(JsToFrontendMap map, |
+ NativeData nativeData, InterceptorDataImpl interceptorData) { |
+ Map<String, Set<MemberEntity>> interceptedMembers = |
+ <String, Set<MemberEntity>>{}; |
+ interceptorData.interceptedMembers |
+ .forEach((String name, Set<MemberEntity> members) { |
+ interceptedMembers[name] = map.toBackendMemberSet(members); |
+ }); |
+ return new InterceptorDataImpl( |
+ nativeData, |
+ _commonElements, |
+ interceptedMembers, |
+ map.toBackendClassSet(interceptorData.interceptedClasses), |
+ map.toBackendClassSet( |
+ interceptorData.classesMixedIntoInterceptedClasses)); |
+ } |
+ |
+ RuntimeTypesNeed _convertRuntimeTypesNeed(JsToFrontendMap map, |
+ BackendUsage backendUsage, RuntimeTypesNeedImpl rtiNeed) { |
+ Set<ClassEntity> classesNeedingRti = |
+ map.toBackendClassSet(rtiNeed.classesNeedingRti); |
+ Set<FunctionEntity> methodsNeedingRti = |
+ map.toBackendFunctionSet(rtiNeed.methodsNeedingRti); |
+ // TODO(johnniwinther): Do we need these? |
+ Set<Local> localFunctionsNeedingRti = rtiNeed.localFunctionsNeedingRti; |
+ Set<ClassEntity> classesUsingTypeVariableExpression = |
+ map.toBackendClassSet(rtiNeed.classesUsingTypeVariableExpression); |
+ return new RuntimeTypesNeedImpl( |
+ _elementEnvironment, |
+ backendUsage, |
+ classesNeedingRti, |
+ methodsNeedingRti, |
+ localFunctionsNeedingRti, |
+ classesUsingTypeVariableExpression); |
+ } |
+ |
@override |
ClosedWorldRefiner createClosedWorldRefiner( |
covariant ClosedWorldBase closedWorld) { |
KernelFrontEndStrategy strategy = _compiler.frontendStrategy; |
- KernelToElementMapForImpact elementMap = strategy.elementMap; |
_elementMap = new JsKernelToElementMap( |
- _compiler.reporter, _compiler.environment, elementMap); |
+ _compiler.reporter, _compiler.environment, strategy.elementMap); |
_elementEnvironment = _elementMap.elementEnvironment; |
_commonElements = _elementMap.commonElements; |
- JsToFrontendMap _map = _elementMap.jsToFrontendMap; |
- BackendUsage backendUsage = |
- new JsBackendUsage(_map, closedWorld.backendUsage); |
+ JsToFrontendMap map = new JsToFrontendMapImpl(_elementMap); |
_closureDataLookup = new KernelClosureConversionTask( |
- _compiler.measurer, _elementMap, _map, _globalLocalsMap); |
- NativeData nativeData = new JsNativeData(_map, closedWorld.nativeData); |
- InterceptorDataImpl interceptorDataImpl = closedWorld.interceptorData; |
- Map<String, Set<MemberEntity>> interceptedMembers = |
- <String, Set<MemberEntity>>{}; |
- interceptorDataImpl.interceptedMembers |
- .forEach((String name, Set<MemberEntity> members) { |
- interceptedMembers[name] = members.map(_map.toBackendMember).toSet(); |
- }); |
- InterceptorData interceptorData = new InterceptorDataImpl( |
- nativeData, |
- _commonElements, |
- interceptedMembers, |
- interceptorDataImpl.interceptedClasses.map(_map.toBackendClass).toSet(), |
- interceptorDataImpl.classesMixedIntoInterceptedClasses |
- .map(_map.toBackendClass) |
- .toSet()); |
+ _compiler.measurer, _elementMap, map, _globalLocalsMap); |
+ |
+ BackendUsage backendUsage = |
+ _convertBackendUsage(map, closedWorld.backendUsage); |
+ NativeData nativeData = _convertNativeData(map, closedWorld.nativeData); |
+ InterceptorData interceptorData = |
+ _convertInterceptorData(map, nativeData, closedWorld.interceptorData); |
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes = |
<ClassEntity, ClassHierarchyNode>{}; |
@@ -90,7 +225,7 @@ class JsBackendStrategy implements KernelBackendStrategy { |
Set<ClassEntity> implementedClasses = new Set<ClassEntity>(); |
ClassHierarchyNode convertClassHierarchyNode(ClassHierarchyNode node) { |
- ClassEntity cls = _map.toBackendClass(node.cls); |
+ ClassEntity cls = map.toBackendClass(node.cls); |
if (closedWorld.isImplemented(node.cls)) { |
implementedClasses.add(cls); |
} |
@@ -107,7 +242,7 @@ class JsBackendStrategy implements KernelBackendStrategy { |
} |
ClassSet convertClassSet(ClassSet classSet) { |
- ClassEntity cls = _map.toBackendClass(classSet.cls); |
+ ClassEntity cls = map.toBackendClass(classSet.cls); |
return classSets.putIfAbsent(cls, () { |
ClassHierarchyNode newNode = convertClassHierarchyNode(classSet.node); |
ClassSet newClassSet = new ClassSet(newNode); |
@@ -125,32 +260,24 @@ class JsBackendStrategy implements KernelBackendStrategy { |
convertClassSet(closedWorld.getClassSet(cls)); |
}, ClassHierarchyNode.ALL); |
- List<MemberEntity> liveInstanceMembers = |
- closedWorld.liveInstanceMembers.map(_map.toBackendMember).toList(); |
+ Set<MemberEntity> liveInstanceMembers = |
+ map.toBackendMemberSet(closedWorld.liveInstanceMembers); |
Map<ClassEntity, Set<ClassEntity>> mixinUses = |
- <ClassEntity, Set<ClassEntity>>{}; |
- closedWorld.mixinUses.forEach((ClassEntity cls, Set<ClassEntity> uses) { |
- mixinUses[_map.toBackendClass(cls)] = |
- uses.map(_map.toBackendClass).toSet(); |
- }); |
+ map.toBackendClassMap(closedWorld.mixinUses, map.toBackendClassSet); |
Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses = |
- <ClassEntity, Set<ClassEntity>>{}; |
- closedWorld.typesImplementedBySubclasses |
- .forEach((ClassEntity cls, Set<ClassEntity> uses) { |
- typesImplementedBySubclasses[_map.toBackendClass(cls)] = |
- uses.map(_map.toBackendClass).toSet(); |
- }); |
+ map.toBackendClassMap( |
+ closedWorld.typesImplementedBySubclasses, map.toBackendClassSet); |
Iterable<MemberEntity> assignedInstanceMembers = |
- closedWorld.assignedInstanceMembers.map(_map.toBackendMember).toList(); |
+ map.toBackendMemberSet(closedWorld.assignedInstanceMembers); |
Iterable<ClassEntity> liveNativeClasses = |
- closedWorld.liveNativeClasses.map(_map.toBackendClass).toList(); |
+ map.toBackendClassSet(closedWorld.liveNativeClasses); |
RuntimeTypesNeed rtiNeed = |
- new JsRuntimeTypesNeed(_map, closedWorld.rtiNeed); |
+ _convertRuntimeTypesNeed(map, backendUsage, closedWorld.rtiNeed); |
return new JsClosedWorld(_elementMap, |
elementEnvironment: _elementEnvironment, |
@@ -216,34 +343,48 @@ class JsBackendStrategy implements KernelBackendStrategy { |
} |
} |
-class JsRuntimeTypesNeed implements RuntimeTypesNeed { |
- final JsToFrontendMap _map; |
- final RuntimeTypesNeed _rtiNeed; |
- |
- JsRuntimeTypesNeed(this._map, this._rtiNeed); |
- |
- @override |
- bool classNeedsRti(ClassEntity cls) { |
- return _rtiNeed.classNeedsRti(_map.toFrontendClass(cls)); |
- } |
- |
- @override |
- bool classUsesTypeVariableExpression(ClassEntity cls) { |
- return _rtiNeed.classUsesTypeVariableExpression(_map.toFrontendClass(cls)); |
- } |
- |
- @override |
- bool localFunctionNeedsRti(Local function) { |
- throw new UnimplementedError('JsRuntimeTypesNeed.localFunctionNeedsRti'); |
- } |
- |
- @override |
- bool methodNeedsRti(FunctionEntity function) { |
- return _rtiNeed.methodNeedsRti(_map.toFrontendMember(function)); |
- } |
+class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin { |
+ final JsKernelToElementMap elementMap; |
+ final RuntimeTypesNeed rtiNeed; |
+ |
+ JsClosedWorld(this.elementMap, |
+ {ElementEnvironment elementEnvironment, |
+ DartTypes dartTypes, |
+ CommonElements commonElements, |
+ ConstantSystem constantSystem, |
+ NativeData nativeData, |
+ InterceptorData interceptorData, |
+ BackendUsage backendUsage, |
+ this.rtiNeed, |
+ Set<ClassEntity> implementedClasses, |
+ Iterable<ClassEntity> liveNativeClasses, |
+ Iterable<MemberEntity> liveInstanceMembers, |
+ Iterable<MemberEntity> assignedInstanceMembers, |
+ Set<TypedefElement> allTypedefs, |
+ Map<ClassEntity, Set<ClassEntity>> mixinUses, |
+ Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, |
+ Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, |
+ Map<ClassEntity, ClassSet> classSets}) |
+ : super( |
+ elementEnvironment, |
+ dartTypes, |
+ commonElements, |
+ constantSystem, |
+ nativeData, |
+ interceptorData, |
+ backendUsage, |
+ implementedClasses, |
+ liveNativeClasses, |
+ liveInstanceMembers, |
+ assignedInstanceMembers, |
+ allTypedefs, |
+ mixinUses, |
+ typesImplementedBySubclasses, |
+ classHierarchyNodes, |
+ classSets); |
@override |
- bool classNeedsRtiField(ClassEntity cls) { |
- return _rtiNeed.classNeedsRtiField(_map.toFrontendClass(cls)); |
+ void registerClosureClass(ClassElement cls) { |
+ throw new UnimplementedError('JsClosedWorld.registerClosureClass'); |
} |
} |