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

Side by Side Diff: pkg/compiler/lib/src/native/enqueue.dart

Issue 2721403006: Split NativeData (Closed)
Patch Set: Created 3 years, 9 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) 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 import '../common.dart'; 5 import '../common.dart';
6 import '../common/backend_api.dart' show ForeignResolver; 6 import '../common/backend_api.dart' show ForeignResolver;
7 import '../common/resolution.dart' show Resolution; 7 import '../common/resolution.dart' show Resolution;
8 import '../compiler.dart' show Compiler; 8 import '../compiler.dart' show Compiler;
9 import '../constants/values.dart'; 9 import '../constants/values.dart';
10 import '../common_elements.dart' show CommonElements; 10 import '../common_elements.dart' show CommonElements;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 107 }
108 processSubclassesOfNativeClasses(libraries); 108 processSubclassesOfNativeClasses(libraries);
109 if (!enableLiveTypeAnalysis) { 109 if (!enableLiveTypeAnalysis) {
110 _registerTypeUses(impactBuilder, _nativeClasses, 'forced'); 110 _registerTypeUses(impactBuilder, _nativeClasses, 'forced');
111 } 111 }
112 } 112 }
113 113
114 void processNativeClassesInLibrary(LibraryElement library) { 114 void processNativeClassesInLibrary(LibraryElement library) {
115 // Use implementation to ensure the inclusion of injected members. 115 // Use implementation to ensure the inclusion of injected members.
116 library.implementation.forEachLocalMember((Element element) { 116 library.implementation.forEachLocalMember((Element element) {
117 if (element.isClass && backend.isNative(element)) { 117 if (element.isClass) {
118 processNativeClass(element); 118 ClassElement cls = element;
119 if (backend.nativeData.isNativeClass(cls)) {
120 processNativeClass(element);
121 }
119 } 122 }
120 }); 123 });
121 } 124 }
122 125
123 void processNativeClass(ClassElement classElement) { 126 void processNativeClass(ClassElement classElement) {
124 _nativeClasses.add(classElement); 127 _nativeClasses.add(classElement);
125 _unusedClasses.add(classElement); 128 _unusedClasses.add(classElement);
126 // Resolve class to ensure the class has valid inheritance info. 129 // Resolve class to ensure the class has valid inheritance info.
127 classElement.ensureResolved(resolution); 130 classElement.ensureResolved(resolution);
128 } 131 }
(...skipping 18 matching lines...) Expand all
147 } 150 }
148 } 151 }
149 }); 152 });
150 }); 153 });
151 154
152 // Resolve all the native classes and any classes that might extend them in 155 // Resolve all the native classes and any classes that might extend them in
153 // [potentialExtends], and then check that the properly resolved class is in 156 // [potentialExtends], and then check that the properly resolved class is in
154 // fact a subclass of a native class. 157 // fact a subclass of a native class.
155 158
156 ClassElement nativeSuperclassOf(ClassElement classElement) { 159 ClassElement nativeSuperclassOf(ClassElement classElement) {
157 if (backend.isNative(classElement)) return classElement; 160 if (backend.nativeData.isNativeClass(classElement)) return classElement;
158 if (classElement.superclass == null) return null; 161 if (classElement.superclass == null) return null;
159 return nativeSuperclassOf(classElement.superclass); 162 return nativeSuperclassOf(classElement.superclass);
160 } 163 }
161 164
162 void walkPotentialSubclasses(ClassElement element) { 165 void walkPotentialSubclasses(ClassElement element) {
163 if (nativeClassesAndSubclasses.contains(element)) return; 166 if (nativeClassesAndSubclasses.contains(element)) return;
164 element.ensureResolved(resolution); 167 element.ensureResolved(resolution);
165 ClassElement nativeSuperclass = nativeSuperclassOf(element); 168 ClassElement nativeSuperclass = nativeSuperclassOf(element);
166 if (nativeSuperclass != null) { 169 if (nativeSuperclass != null) {
167 nativeClassesAndSubclasses.add(element); 170 nativeClassesAndSubclasses.add(element);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 cls.ensureResolved(resolution); 295 cls.ensureResolved(resolution);
293 impactBuilder 296 impactBuilder
294 .registerTypeUse(new TypeUse.nativeInstantiation(cls.rawType)); 297 .registerTypeUse(new TypeUse.nativeInstantiation(cls.rawType));
295 } 298 }
296 } 299 }
297 300
298 void handleFieldAnnotations(Element element) { 301 void handleFieldAnnotations(Element element) {
299 if (compiler.serialization.isDeserialized(element)) { 302 if (compiler.serialization.isDeserialized(element)) {
300 return; 303 return;
301 } 304 }
302 if (backend.isNative(element.enclosingElement)) { 305 if (element.isInstanceMember &&
303 // Exclude non-instance (static) fields - they not really native and are 306 backend.nativeData.isNativeClass(element.enclosingClass)) {
304 // compiled as isolate globals. Access of a property of a constructor 307 // Exclude non-instance (static) fields - they are not really native and
308 // are compiled as isolate globals. Access of a property of a constructor
305 // function or a non-method property in the prototype chain, must be coded 309 // function or a non-method property in the prototype chain, must be coded
306 // using a JS-call. 310 // using a JS-call.
307 if (element.isInstanceMember) { 311 _setNativeName(element);
308 _setNativeName(element);
309 }
310 } 312 }
311 } 313 }
312 314
313 void handleMethodAnnotations(Element method) { 315 void handleMethodAnnotations(Element method) {
314 if (compiler.serialization.isDeserialized(method)) { 316 if (compiler.serialization.isDeserialized(method)) {
315 return; 317 return;
316 } 318 }
317 if (isNativeMethod(method)) { 319 if (isNativeMethod(method)) {
318 if (method.isStatic) { 320 if (method.isStatic) {
319 _setNativeNameForStaticMethod(method); 321 _setNativeNameForStaticMethod(method);
320 } else { 322 } else {
321 _setNativeName(method); 323 _setNativeName(method);
322 } 324 }
323 } 325 }
324 } 326 }
325 327
326 /// Sets the native name of [element], either from an annotation, or 328 /// Sets the native name of [element], either from an annotation, or
327 /// defaulting to the Dart name. 329 /// defaulting to the Dart name.
328 void _setNativeName(MemberElement element) { 330 void _setNativeName(MemberElement element) {
329 String name = findJsNameFromAnnotation(element); 331 String name = findJsNameFromAnnotation(element);
330 if (name == null) name = element.name; 332 if (name == null) name = element.name;
331 backend.nativeData.setNativeMemberName(element, name); 333 backend.nativeDataBuilder.setNativeMemberName(element, name);
332 } 334 }
333 335
334 /// Sets the native name of the static native method [element], using the 336 /// Sets the native name of the static native method [element], using the
335 /// following rules: 337 /// following rules:
336 /// 1. If [element] has a @JSName annotation that is an identifier, qualify 338 /// 1. If [element] has a @JSName annotation that is an identifier, qualify
337 /// that identifier to the @Native name of the enclosing class 339 /// that identifier to the @Native name of the enclosing class
338 /// 2. If [element] has a @JSName annotation that is not an identifier, 340 /// 2. If [element] has a @JSName annotation that is not an identifier,
339 /// use the declared @JSName as the expression 341 /// use the declared @JSName as the expression
340 /// 3. If [element] does not have a @JSName annotation, qualify the name of 342 /// 3. If [element] does not have a @JSName annotation, qualify the name of
341 /// the method with the @Native name of the enclosing class. 343 /// the method with the @Native name of the enclosing class.
342 void _setNativeNameForStaticMethod(MethodElement element) { 344 void _setNativeNameForStaticMethod(MethodElement element) {
343 String name = findJsNameFromAnnotation(element); 345 String name = findJsNameFromAnnotation(element);
344 if (name == null) name = element.name; 346 if (name == null) name = element.name;
345 if (isIdentifier(name)) { 347 if (isIdentifier(name)) {
346 List<String> nativeNames = 348 List<String> nativeNames = backend.nativeDataBuilder
347 backend.nativeData.getNativeTagsOfClassRaw(element.enclosingClass); 349 .getNativeTagsOfClassRaw(element.enclosingClass);
348 if (nativeNames.length != 1) { 350 if (nativeNames.length != 1) {
349 reporter.internalError( 351 reporter.internalError(
350 element, 352 element,
351 'Unable to determine a native name for the enclosing class, ' 353 'Unable to determine a native name for the enclosing class, '
352 'options: $nativeNames'); 354 'options: $nativeNames');
353 } 355 }
354 backend.nativeData 356 backend.nativeDataBuilder
355 .setNativeMemberName(element, '${nativeNames[0]}.$name'); 357 .setNativeMemberName(element, '${nativeNames[0]}.$name');
356 } else { 358 } else {
357 backend.nativeData.setNativeMemberName(element, name); 359 backend.nativeDataBuilder.setNativeMemberName(element, name);
358 } 360 }
359 } 361 }
360 362
361 bool isIdentifier(String s) => _identifier.hasMatch(s); 363 bool isIdentifier(String s) => _identifier.hasMatch(s);
362 364
363 bool isNativeMethod(FunctionElementX element) { 365 bool isNativeMethod(FunctionElementX element) {
364 if (!backend.canLibraryUseNative(element.library)) return false; 366 if (!backend.canLibraryUseNative(element.library)) return false;
365 // Native method? 367 // Native method?
366 return reporter.withCurrentElement(element, () { 368 return reporter.withCurrentElement(element, () {
367 Node node = element.parseNode(resolution.parsingContext); 369 Node node = element.parseNode(resolution.parsingContext);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 480
479 void registerBackendUse(MethodElement element) { 481 void registerBackendUse(MethodElement element) {
480 _backendUsageBuilder.registerBackendFunctionUse(element); 482 _backendUsageBuilder.registerBackendFunctionUse(element);
481 _backendUsageBuilder.registerGlobalFunctionDependency(element); 483 _backendUsageBuilder.registerGlobalFunctionDependency(element);
482 } 484 }
483 485
484 void processNativeClass(ClassElement classElement) { 486 void processNativeClass(ClassElement classElement) {
485 super.processNativeClass(classElement); 487 super.processNativeClass(classElement);
486 488
487 // Js Interop interfaces do not have tags. 489 // Js Interop interfaces do not have tags.
488 if (backend.isJsInterop(classElement)) return; 490 if (backend.nativeData.isJsInterop(classElement)) return;
489 // Since we map from dispatch tags to classes, a dispatch tag must be used 491 // Since we map from dispatch tags to classes, a dispatch tag must be used
490 // on only one native class. 492 // on only one native class.
491 for (String tag in backend.nativeData.getNativeTagsOfClass(classElement)) { 493 for (String tag in backend.nativeData.getNativeTagsOfClass(classElement)) {
492 ClassElement owner = tagOwner[tag]; 494 ClassElement owner = tagOwner[tag];
493 if (owner != null) { 495 if (owner != null) {
494 if (owner != classElement) { 496 if (owner != classElement) {
495 reporter.internalError( 497 reporter.internalError(
496 classElement, "Tag '$tag' already in use by '${owner.name}'"); 498 classElement, "Tag '$tag' already in use by '${owner.name}'");
497 } 499 }
498 } else { 500 } else {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 super._registerTypeUses(impactBuilder, classes, cause); 583 super._registerTypeUses(impactBuilder, classes, cause);
582 584
583 for (ClassElement classElement in classes) { 585 for (ClassElement classElement in classes) {
584 // Add the information that this class is a subtype of its supertypes. The 586 // Add the information that this class is a subtype of its supertypes. The
585 // code emitter and the ssa builder use that information. 587 // code emitter and the ssa builder use that information.
586 _addSubtypes(classElement, emitter.nativeEmitter); 588 _addSubtypes(classElement, emitter.nativeEmitter);
587 } 589 }
588 } 590 }
589 591
590 void _addSubtypes(ClassElement cls, NativeEmitter emitter) { 592 void _addSubtypes(ClassElement cls, NativeEmitter emitter) {
591 if (!backend.isNative(cls)) return; 593 if (!backend.nativeData.isNativeClass(cls)) return;
592 if (doneAddSubtypes.contains(cls)) return; 594 if (doneAddSubtypes.contains(cls)) return;
593 doneAddSubtypes.add(cls); 595 doneAddSubtypes.add(cls);
594 596
595 // Walk the superclass chain since classes on the superclass chain might not 597 // Walk the superclass chain since classes on the superclass chain might not
596 // be instantiated (abstract or simply unused). 598 // be instantiated (abstract or simply unused).
597 _addSubtypes(cls.superclass, emitter); 599 _addSubtypes(cls.superclass, emitter);
598 600
599 for (ResolutionInterfaceType type in cls.allSupertypes) { 601 for (ResolutionInterfaceType type in cls.allSupertypes) {
600 List<ClassEntity> subtypes = 602 List<ClassEntity> subtypes =
601 emitter.subtypes.putIfAbsent(type.element, () => <ClassEntity>[]); 603 emitter.subtypes.putIfAbsent(type.element, () => <ClassEntity>[]);
602 subtypes.add(cls); 604 subtypes.add(cls);
603 } 605 }
604 606
605 // Skip through all the mixin applications in the super class 607 // Skip through all the mixin applications in the super class
606 // chain. That way, the direct subtypes set only contain the 608 // chain. That way, the direct subtypes set only contain the
607 // natives classes. 609 // natives classes.
608 ClassElement superclass = cls.superclass; 610 ClassElement superclass = cls.superclass;
609 while (superclass != null && superclass.isMixinApplication) { 611 while (superclass != null && superclass.isMixinApplication) {
610 assert(!backend.isNative(superclass)); 612 assert(!backend.nativeData.isNativeClass(superclass));
611 superclass = superclass.superclass; 613 superclass = superclass.superclass;
612 } 614 }
613 615
614 List<ClassEntity> directSubtypes = 616 List<ClassEntity> directSubtypes =
615 emitter.directSubtypes.putIfAbsent(superclass, () => <ClassEntity>[]); 617 emitter.directSubtypes.putIfAbsent(superclass, () => <ClassEntity>[]);
616 directSubtypes.add(cls); 618 directSubtypes.add(cls);
617 } 619 }
618 620
619 void logSummary(log(message)) { 621 void logSummary(log(message)) {
620 log('Compiled ${_registeredClasses.length} native classes, ' 622 log('Compiled ${_registeredClasses.length} native classes, '
621 '${_unusedClasses.length} native classes omitted.'); 623 '${_unusedClasses.length} native classes omitted.');
622 } 624 }
623 } 625 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698