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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart

Issue 13973017: Revert "Revert "Allow multiple tags in native clause."" (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase Created 7 years, 8 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 | 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 part of js_backend; 5 part of js_backend;
6 6
7 class NativeEmitter { 7 class NativeEmitter {
8 8
9 CodeEmitterTask emitter; 9 CodeEmitterTask emitter;
10 CodeBuffer nativeBuffer; 10 CodeBuffer nativeBuffer;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 const SourceString('defineNativeMethodsNonleaf')); 92 const SourceString('defineNativeMethodsNonleaf'));
93 return backend.namer.isolateAccess(element); 93 return backend.namer.isolateAccess(element);
94 } 94 }
95 95
96 String get defineNativeMethodsFinishName { 96 String get defineNativeMethodsFinishName {
97 Element element = compiler.findHelper( 97 Element element = compiler.findHelper(
98 const SourceString('defineNativeMethodsFinish')); 98 const SourceString('defineNativeMethodsFinish'));
99 return backend.namer.isolateAccess(element); 99 return backend.namer.isolateAccess(element);
100 } 100 }
101 101
102 bool isNativeGlobal(String quotedName) { 102 List<String> nativeTagsOfClass(ClassElement cls) {
103 return identical(quotedName[1], '@');
104 }
105
106 String toNativeTag(ClassElement cls) {
107 String quotedName = cls.nativeTagInfo.slowToString(); 103 String quotedName = cls.nativeTagInfo.slowToString();
108 if (isNativeGlobal(quotedName)) { 104 return quotedName.substring(1, quotedName.length - 1).split(',');
109 // Global object, just be like the other types for now.
110 return quotedName.substring(3, quotedName.length - 1);
111 } else {
112 return quotedName.substring(2, quotedName.length - 1);
113 }
114 } 105 }
115 106
116 /** 107 /**
117 * Writes the class definitions for the interceptors to [mainBuffer]. 108 * Writes the class definitions for the interceptors to [mainBuffer].
118 * Writes code to associate dispatch tags with interceptors to [nativeBuffer]. 109 * Writes code to associate dispatch tags with interceptors to [nativeBuffer].
119 * 110 *
120 * The interceptors are filtered to avoid emitting trivial interceptors. For 111 * The interceptors are filtered to avoid emitting trivial interceptors. For
121 * example, if the program contains no code that can distinguish between the 112 * example, if the program contains no code that can distinguish between the
122 * numerous subclasses of `Element` then we can pretend that `Element` is a 113 * numerous subclasses of `Element` then we can pretend that `Element` is a
123 * leaf class, and all instances of subclasses of `Element` are instances of 114 * leaf class, and all instances of subclasses of `Element` are instances of
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // TODO(9556): We can't remove any unneeded classes until the class 169 // TODO(9556): We can't remove any unneeded classes until the class
179 // builders contain all the information. [emitRuntimeTypeSupport] must 170 // builders contain all the information. [emitRuntimeTypeSupport] must
180 // no longer add information to a class definition. 171 // no longer add information to a class definition.
181 needed = true; 172 needed = true;
182 } 173 }
183 174
184 // BUG. There is a missing proto in the picture the DOM gives of the 175 // BUG. There is a missing proto in the picture the DOM gives of the
185 // proto chain. 176 // proto chain.
186 // TODO(9907): Fix DOM generation. We might need an annotation. 177 // TODO(9907): Fix DOM generation. We might need an annotation.
187 if (classElement.isNative()) { 178 if (classElement.isNative()) {
188 String nativeTag = toNativeTag(classElement); 179 List<String> nativeTags = nativeTagsOfClass(classElement);
189 if (nativeTag == 'HTMLElement') { 180 if (nativeTags.contains('HTMLElement')) {
190 nonleafClasses.add(classElement); 181 nonleafClasses.add(classElement);
191 needed = true; 182 needed = true;
192 } 183 }
193 } 184 }
194 185
195 if (needed || neededClasses.contains(classElement)) { 186 if (needed || neededClasses.contains(classElement)) {
196 neededClasses.add(classElement); 187 neededClasses.add(classElement);
197 neededClasses.add(classElement.superclass); 188 neededClasses.add(classElement.superclass);
198 nonleafClasses.add(classElement.superclass); 189 nonleafClasses.add(classElement.superclass);
199 } 190 }
200 } 191 }
201 192
202 // Collect all the tags that map to each class. 193 // Collect all the tags that map to each class.
203 194
204 Map<ClassElement, Set<String>> leafTags = 195 Map<ClassElement, Set<String>> leafTags =
205 new Map<ClassElement, Set<String>>(); 196 new Map<ClassElement, Set<String>>();
206 Map<ClassElement, Set<String>> nonleafTags = 197 Map<ClassElement, Set<String>> nonleafTags =
207 new Map<ClassElement, Set<String>>(); 198 new Map<ClassElement, Set<String>>();
208 199
209 for (ClassElement classElement in classes) { 200 for (ClassElement classElement in classes) {
210 String nativeTag = toNativeTag(classElement); 201 List<String> nativeTags = nativeTagsOfClass(classElement);
211 202
212 if (nonleafClasses.contains(classElement)) { 203 if (nonleafClasses.contains(classElement)) {
213 nonleafTags 204 nonleafTags
214 .putIfAbsent(classElement, () => new Set<String>()) 205 .putIfAbsent(classElement, () => new Set<String>())
215 .add(nativeTag); 206 .addAll(nativeTags);
216 } else { 207 } else {
217 ClassElement sufficingInterceptor = classElement; 208 ClassElement sufficingInterceptor = classElement;
218 while (!neededClasses.contains(sufficingInterceptor)) { 209 while (!neededClasses.contains(sufficingInterceptor)) {
219 sufficingInterceptor = sufficingInterceptor.superclass; 210 sufficingInterceptor = sufficingInterceptor.superclass;
220 } 211 }
221 if (sufficingInterceptor == compiler.objectClass) { 212 if (sufficingInterceptor == compiler.objectClass) {
222 sufficingInterceptor = backend.jsInterceptorClass; 213 sufficingInterceptor = backend.jsInterceptorClass;
223 } 214 }
224 leafTags 215 leafTags
225 .putIfAbsent(sufficingInterceptor, () => new Set<String>()) 216 .putIfAbsent(sufficingInterceptor, () => new Set<String>())
226 .add(nativeTag); 217 .addAll(nativeTags);
227 } 218 }
228 } 219 }
229 220
230 // Emit code to set up dispatch data that maps tags to the interceptors. 221 // Emit code to set up dispatch data that maps tags to the interceptors.
231 222
232 void generateDefines(ClassElement classElement) { 223 void generateDefines(ClassElement classElement) {
233 generateDefineNativeMethods(leafTags[classElement], classElement, 224 generateDefineNativeMethods(leafTags[classElement], classElement,
234 defineNativeMethodsName); 225 defineNativeMethodsName);
235 generateDefineNativeMethods(nonleafTags[classElement], classElement, 226 generateDefineNativeMethods(nonleafTags[classElement], classElement,
236 defineNativeMethodsNonleafName); 227 defineNativeMethodsNonleafName);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 if (!hasFields && builder.properties.length == propertyCount) { 274 if (!hasFields && builder.properties.length == propertyCount) {
284 builder.isTrivial = true; 275 builder.isTrivial = true;
285 } 276 }
286 277
287 return builder; 278 return builder;
288 } 279 }
289 280
290 void generateDefineNativeMethods( 281 void generateDefineNativeMethods(
291 Set<String> tags, ClassElement classElement, String definer) { 282 Set<String> tags, ClassElement classElement, String definer) {
292 if (tags == null) return; 283 if (tags == null) return;
293
294 String tagsString = (tags.toList()..sort()).join('|'); 284 String tagsString = (tags.toList()..sort()).join('|');
295 jsAst.Expression definition = 285 jsAst.Expression definition =
296 js(definer)( 286 js(definer)(
297 [js.string(tagsString), 287 [js.string(tagsString),
298 js(backend.namer.isolateAccess(classElement))]); 288 js(backend.namer.isolateAccess(classElement))]);
299 289
300 nativeBuffer.add(jsAst.prettyPrint(definition, compiler)); 290 nativeBuffer.add(jsAst.prettyPrint(definition, compiler));
301 nativeBuffer.add('$N$n'); 291 nativeBuffer.add('$N$n');
302 } 292 }
303 293
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 // The target JS function may check arguments.length so we need to 342 // The target JS function may check arguments.length so we need to
353 // make sure not to pass any unspecified optional arguments to it. 343 // make sure not to pass any unspecified optional arguments to it.
354 // For example, for the following Dart method: 344 // For example, for the following Dart method:
355 // foo([x, y, z]); 345 // foo([x, y, z]);
356 // The call: 346 // The call:
357 // foo(y: 1) 347 // foo(y: 1)
358 // must be turned into a JS call to: 348 // must be turned into a JS call to:
359 // foo(null, y). 349 // foo(null, y).
360 350
361 ClassElement classElement = member.enclosingElement; 351 ClassElement classElement = member.enclosingElement;
362 String nativeTagInfo = classElement.nativeTagInfo.slowToString();
363 352
364 List<jsAst.Statement> statements = <jsAst.Statement>[]; 353 List<jsAst.Statement> statements = <jsAst.Statement>[];
365 potentiallyConvertDartClosuresToJs(statements, member, stubParameters); 354 potentiallyConvertDartClosuresToJs(statements, member, stubParameters);
366 355
367 String target; 356 String target;
368 jsAst.Expression receiver; 357 jsAst.Expression receiver;
369 List<jsAst.Expression> arguments; 358 List<jsAst.Expression> arguments;
370 359
371 if (!nativeMethods.contains(member)) { 360 if (!nativeMethods.contains(member)) {
372 // When calling a method that has a native body, we call it with our 361 // When calling a method that has a native body, we call it with our
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 if (emitter.compiler.enableMinification) targetBuffer.add(';'); 447 if (emitter.compiler.enableMinification) targetBuffer.add(';');
459 targetBuffer.add(jsAst.prettyPrint( 448 targetBuffer.add(jsAst.prettyPrint(
460 new jsAst.ExpressionStatement(init), compiler)); 449 new jsAst.ExpressionStatement(init), compiler));
461 targetBuffer.add('\n'); 450 targetBuffer.add('\n');
462 } 451 }
463 452
464 targetBuffer.add(nativeBuffer); 453 targetBuffer.add(nativeBuffer);
465 targetBuffer.add('\n'); 454 targetBuffer.add('\n');
466 } 455 }
467 } 456 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698