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

Side by Side Diff: lib/compiler/implementation/native_handler.dart

Issue 11304021: Add NativeEnqueuer to work with the Enqueuer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 native; 5 library native;
6 6
7 import 'dart:uri'; 7 import 'dart:uri';
8 import 'dart2jslib.dart' hide SourceString; 8 import 'dart2jslib.dart' hide SourceString;
9 import 'elements/elements.dart'; 9 import 'elements/elements.dart';
10 import 'js_backend/js_backend.dart'; 10 import 'js_backend/js_backend.dart';
11 import 'scanner/scannerlib.dart'; 11 import 'scanner/scannerlib.dart';
12 import 'ssa/ssa.dart'; 12 import 'ssa/ssa.dart';
13 import 'tree/tree.dart'; 13 import 'tree/tree.dart';
14 import 'util/util.dart'; 14 import 'util/util.dart';
15 15
16 void processNativeClasses(Enqueuer world, 16
17 CodeEmitterTask emitter, 17 // This could be an abstract class but we use it as a stub for the dart_backend.
18 Collection<LibraryElement> libraries) { 18 class NativeEnqueuer {
19 for (LibraryElement library in libraries) { 19 void processNativeClasses(Collection<LibraryElement> libraries) {}
20 processNativeClassesInLibrary(world, emitter, library); 20
21
22 void registerElement(Element element) {}
23
24 // Method is a member of a native class.
25 void registerMethod(Element method) {}
26
27 // Field is a member of a native class.
28 void registerFieldLoad(FieldElement field) {}
29 void registerFieldStore(FieldElement field) {}
30
31 // JS-form code can be an instantiation point for types.
32 //
33 // JS('_DOMWindowImpl', 'window');
34 //
35 // TODO(sra): Who calls this?
36 // TODO(sra): How do we parse the type?
37 void registerJS(code) {}
38 }
39
40
41 class NativeEnqueuerBase implements NativeEnqueuer {
42
43 final Set<ClassElement> nativeClasses = new Set<ClassElement>();
44 final Set<ClassElement> registeredClasses = new Set<ClassElement>();
45 final Set<ClassElement> unusedClasses = new Set<ClassElement>();
46
47 final Enqueuer world;
48 final Compiler compiler;
49
50 // constructed by backend.
51 NativeEnqueuerBase(this.world, this.compiler);
52
53 void processNativeClasses(Collection<LibraryElement> libraries) {
54 libraries.forEach(processNativeClassesInLibrary);
55
56 // TODO(sra): Register classes that liveness analysis misses, e.g. DOM
57 // exception classes. Could to it at the first class.
58
59 //nativeClasses.forEach(registerClass);
sra1 2012/10/27 01:00:48 Uncomment to go back to registering everything.
60 }
61
62 void processNativeClassesInLibrary(LibraryElement library) {
63 // Use implementation to ensure the inclusion of injected members.
64 library.implementation.forEachLocalMember((Element element) {
65 if (element.kind == ElementKind.CLASS) {
66 ClassElement classElement = element;
67 if (classElement.isNative()) {
68 nativeClasses.add(classElement);
69 unusedClasses.add(classElement);
70 }
71 }
72 });
73 }
74
75 /// Action to process
76 registerClass(ClassElement classElement) {
77 assert(!registerClass.contains(classElement));
78 if (registeredClasses.isEmpty) {
79 onFirstNativeClass();
80 }
81 registeredClasses.add(classElement);
82 unusedClasses.remove(classElement);
83 world.registerInstantiatedClass(classElement);
84 // Also parse the node to know all its methods because
85 // otherwise it will only be parsed if there is a call to
86 // one of its constructors.
87 classElement.parseNode(compiler);
88 // Resolve to setup the inheritance.
89 classElement.ensureResolved(compiler);
90 }
91
92 registerElement(Element element) {
93 print('registerElement $element');
94 if (element.isFunction) return registerMethod(element);
95 }
96
97 registerMethod(Element method) {
98 captureType(method.computeType(compiler));
99 }
100
101 registerFieldLoad(FieldElement field) {
102 captureType(field.computeType(compiler));
103 }
104
105 registerFieldStore(FieldElement field) {
106 escapeType(field.computeType(compiler));
107 }
108
109 escapeType(DartType type) {
110 }
111
112 captureType(DartType type) {
113 if (type is FunctionType) {
114 captureType(type.returnType);
115 } else {
116 if (type.element.kind == Element.CLASS) {
117 ClassElement classElement = type.element;
118 // All native classes that are, implement, or extend classElement.
119 if (classElement.isNative && unusedClasses.contains(classElement)) {
120 registerClass(classElement);
121 }
122 }
123 }
124 }
125
126 onFirstNativeClass() {
127 staticUse(name) => world.registerStaticUse(compiler.findHelper(name));
128
129 staticUse(const SourceString('dynamicFunction'));
130 staticUse(const SourceString('dynamicSetMetadata'));
131 staticUse(const SourceString('defineProperty'));
132 staticUse(const SourceString('toStringForNativeObject'));
133 staticUse(const SourceString('hashCodeForNativeObject'));
21 } 134 }
22 } 135 }
23 136
24 void addSubtypes(ClassElement cls, 137 class NativeResolutionEnqueuer extends NativeEnqueuerBase {
25 NativeEmitter emitter) { 138
26 for (DartType type in cls.allSupertypes) { 139 NativeResolutionEnqueuer(Enqueuer world, Compiler compiler)
27 List<Element> subtypes = emitter.subtypes.putIfAbsent( 140 : super(world, compiler);
28 type.element, 141 }
29 () => <ClassElement>[]); 142
30 subtypes.add(cls); 143 class NativeCodegenEnqueuer extends NativeEnqueuerBase {
144
145 final CodeEmitterTask emitter;
146
147 NativeCodegenEnqueuer(Enqueuer world, Compiler compiler, this.emitter)
148 : super(world, compiler);
149
150 registerClass(ClassElement classElement) {
151 super.registerClass(classElement);
152 // Add the information that this class is a subtype of
153 // its supertypes. The code emitter and the ssa builder use that
sra1 2012/10/27 01:00:48 Nicolas: How and when does the ssa builder use thi
ngeoffray 2012/10/29 14:10:47 That's in handleSsaNative in this file: method isO
154 // information.
155 addSubtypes(classElement, emitter.nativeEmitter);
31 } 156 }
32 157
33 List<Element> directSubtypes = emitter.directSubtypes.putIfAbsent( 158 void addSubtypes(ClassElement cls, NativeEmitter emitter) {
34 cls.superclass, 159 for (DartType type in cls.allSupertypes) {
35 () => <ClassElement>[]); 160 List<Element> subtypes = emitter.subtypes.putIfAbsent(
36 directSubtypes.add(cls); 161 type.element,
37 } 162 () => <ClassElement>[]);
163 subtypes.add(cls);
164 }
38 165
39 void processNativeClassesInLibrary(Enqueuer world, 166 List<Element> directSubtypes = emitter.directSubtypes.putIfAbsent(
40 CodeEmitterTask emitter, 167 cls.superclass,
41 LibraryElement library) { 168 () => <ClassElement>[]);
42 bool hasNativeClass = false; 169 directSubtypes.add(cls);
43 final compiler = emitter.compiler;
44 // Use implementation to ensure the inclusion of injected members.
45 library.implementation.forEachLocalMember((Element element) {
46 if (element.kind == ElementKind.CLASS) {
47 ClassElement classElement = element;
48 if (classElement.isNative()) {
49 hasNativeClass = true;
50 world.registerInstantiatedClass(classElement);
51 // Also parse the node to know all its methods because
52 // otherwise it will only be parsed if there is a call to
53 // one of its constructor.
54 classElement.parseNode(compiler);
55 // Resolve to setup the inheritance.
56 classElement.ensureResolved(compiler);
57 // Add the information that this class is a subtype of
58 // its supertypes. The code emitter and the ssa builder use that
59 // information.
60 addSubtypes(classElement, emitter.nativeEmitter);
61 }
62 }
63 });
64 if (hasNativeClass) {
65 world.registerStaticUse(compiler.findHelper(
66 const SourceString('dynamicFunction')));
67 world.registerStaticUse(compiler.findHelper(
68 const SourceString('dynamicSetMetadata')));
69 world.registerStaticUse(compiler.findHelper(
70 const SourceString('defineProperty')));
71 world.registerStaticUse(compiler.findHelper(
72 const SourceString('toStringForNativeObject')));
73 world.registerStaticUse(compiler.findHelper(
74 const SourceString('hashCodeForNativeObject')));
75 } 170 }
171
76 } 172 }
77 173
78 void maybeEnableNative(Compiler compiler, 174 void maybeEnableNative(Compiler compiler,
79 LibraryElement library, 175 LibraryElement library,
80 Uri uri) { 176 Uri uri) {
81 String libraryName = uri.toString(); 177 String libraryName = uri.toString();
82 if (library.entryCompilationUnit.script.name.contains( 178 if (library.entryCompilationUnit.script.name.contains(
83 'dart/tests/compiler/dart2js_native') 179 'dart/tests/compiler/dart2js_native')
84 || libraryName == 'dart:isolate' 180 || libraryName == 'dart:isolate'
85 || libraryName == 'dart:html') { 181 || libraryName == 'dart:html') {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 String parameters) { 427 String parameters) {
332 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty"); 428 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty");
333 buffer.add("('$methodName')) {\n"); 429 buffer.add("('$methodName')) {\n");
334 buffer.add(" $code"); 430 buffer.add(" $code");
335 buffer.add(" } else {\n"); 431 buffer.add(" } else {\n");
336 buffer.add(" return Object.prototype.$methodName.call(this"); 432 buffer.add(" return Object.prototype.$methodName.call(this");
337 buffer.add(parameters == '' ? '' : ', $parameters'); 433 buffer.add(parameters == '' ? '' : ', $parameters');
338 buffer.add(");\n"); 434 buffer.add(");\n");
339 buffer.add(" }\n"); 435 buffer.add(" }\n");
340 } 436 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/js_backend/backend.dart ('k') | pkg/dartdoc/lib/src/mirrors/dart2js_mirror.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698