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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/native_emitter.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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
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 dart2js.js_emitter; 5 part of dart2js.js_emitter;
6 6
7 class NativeEmitter { 7 class NativeEmitter {
8
9 // TODO(floitsch): the native-emitter should not know about ClassBuilders. 8 // TODO(floitsch): the native-emitter should not know about ClassBuilders.
10 final Map<Element, full_js_emitter.ClassBuilder> cachedBuilders; 9 final Map<Element, full_js_emitter.ClassBuilder> cachedBuilders;
11 10
12 final CodeEmitterTask emitterTask; 11 final CodeEmitterTask emitterTask;
13 12
14 // Whether the application contains native classes. 13 // Whether the application contains native classes.
15 bool hasNativeClasses = false; 14 bool hasNativeClasses = false;
16 15
17 // Caches the native subtypes of a native class. 16 // Caches the native subtypes of a native class.
18 Map<ClassElement, List<ClassElement>> subtypes; 17 Map<ClassElement, List<ClassElement>> subtypes;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 * 63 *
65 * [classes] contains native classes, mixin applications, and user subclasses 64 * [classes] contains native classes, mixin applications, and user subclasses
66 * of native classes. 65 * of native classes.
67 * 66 *
68 * [interceptorClassesNeededByConstants] contains the interceptors that are 67 * [interceptorClassesNeededByConstants] contains the interceptors that are
69 * referenced by constants. 68 * referenced by constants.
70 * 69 *
71 * [classesModifiedByEmitRTISupport] contains the list of classes that must 70 * [classesModifiedByEmitRTISupport] contains the list of classes that must
72 * exist, because runtime-type support adds information to the class. 71 * exist, because runtime-type support adds information to the class.
73 */ 72 */
74 Set<Class> prepareNativeClasses(List<Class> classes, 73 Set<Class> prepareNativeClasses(
74 List<Class> classes,
75 Set<ClassElement> interceptorClassesNeededByConstants, 75 Set<ClassElement> interceptorClassesNeededByConstants,
76 Set<ClassElement> classesModifiedByEmitRTISupport) { 76 Set<ClassElement> classesModifiedByEmitRTISupport) {
77 assert(classes.every((Class cls) => cls != null)); 77 assert(classes.every((Class cls) => cls != null));
78 78
79 hasNativeClasses = classes.isNotEmpty; 79 hasNativeClasses = classes.isNotEmpty;
80 80
81 // Compute a pre-order traversal of the subclass forest. We actually want a 81 // Compute a pre-order traversal of the subclass forest. We actually want a
82 // post-order traversal but it is easier to compute the pre-order and use it 82 // post-order traversal but it is easier to compute the pre-order and use it
83 // in reverse. 83 // in reverse.
84 List<Class> preOrder = <Class>[]; 84 List<Class> preOrder = <Class>[];
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 } else if (interceptorClassesNeededByConstants.contains(classElement)) { 130 } else if (interceptorClassesNeededByConstants.contains(classElement)) {
131 needed = true; 131 needed = true;
132 } else if (classesModifiedByEmitRTISupport.contains(classElement)) { 132 } else if (classesModifiedByEmitRTISupport.contains(classElement)) {
133 // TODO(9556): Remove this test when [emitRuntimeTypeSupport] no longer 133 // TODO(9556): Remove this test when [emitRuntimeTypeSupport] no longer
134 // adds information to a class prototype or constructor. 134 // adds information to a class prototype or constructor.
135 needed = true; 135 needed = true;
136 } else if (extensionPoints.containsKey(cls)) { 136 } else if (extensionPoints.containsKey(cls)) {
137 needed = true; 137 needed = true;
138 } 138 }
139 if (backend.isJsInterop(classElement)) { 139 if (backend.isJsInterop(classElement)) {
140 needed = true; // TODO(jacobr): we don't need all interop classes. 140 needed = true; // TODO(jacobr): we don't need all interop classes.
141 } else if (cls.isNative && 141 } else if (cls.isNative &&
142 backend.nativeData.hasNativeTagsForcedNonLeaf(classElement)) { 142 backend.nativeData.hasNativeTagsForcedNonLeaf(classElement)) {
143 needed = true; 143 needed = true;
144 nonLeafClasses.add(cls); 144 nonLeafClasses.add(cls);
145 } 145 }
146 146
147 if (needed || neededClasses.contains(cls)) { 147 if (needed || neededClasses.contains(cls)) {
148 neededClasses.add(cls); 148 neededClasses.add(cls);
149 neededClasses.add(cls.superclass); 149 neededClasses.add(cls.superclass);
150 nonLeafClasses.add(cls.superclass); 150 nonLeafClasses.add(cls.superclass);
151 } 151 }
152 } 152 }
153 153
154 // Collect all the tags that map to each native class. 154 // Collect all the tags that map to each native class.
155 155
156 Map<Class, Set<String>> leafTags = new Map<Class, Set<String>>(); 156 Map<Class, Set<String>> leafTags = new Map<Class, Set<String>>();
157 Map<Class, Set<String>> nonleafTags = new Map<Class, Set<String>>(); 157 Map<Class, Set<String>> nonleafTags = new Map<Class, Set<String>>();
158 158
159 for (Class cls in classes) { 159 for (Class cls in classes) {
160 if (!cls.isNative) continue; 160 if (!cls.isNative) continue;
161 if (backend.isJsInterop(cls.element)) continue; 161 if (backend.isJsInterop(cls.element)) continue;
162 List<String> nativeTags = 162 List<String> nativeTags =
163 backend.nativeData.getNativeTagsOfClass(cls.element); 163 backend.nativeData.getNativeTagsOfClass(cls.element);
164 164
165 if (nonLeafClasses.contains(cls) || 165 if (nonLeafClasses.contains(cls) || extensionPoints.containsKey(cls)) {
166 extensionPoints.containsKey(cls)) {
167 nonleafTags 166 nonleafTags
168 .putIfAbsent(cls, () => new Set<String>()) 167 .putIfAbsent(cls, () => new Set<String>())
169 .addAll(nativeTags); 168 .addAll(nativeTags);
170 } else { 169 } else {
171 Class sufficingInterceptor = cls; 170 Class sufficingInterceptor = cls;
172 while (!neededClasses.contains(sufficingInterceptor)) { 171 while (!neededClasses.contains(sufficingInterceptor)) {
173 sufficingInterceptor = sufficingInterceptor.superclass; 172 sufficingInterceptor = sufficingInterceptor.superclass;
174 } 173 }
175 if (sufficingInterceptor == objectClass) { 174 if (sufficingInterceptor == objectClass) {
176 sufficingInterceptor = jsInterceptorClass; 175 sufficingInterceptor = jsInterceptorClass;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 Class nativeAncestorOf(Class cls) { 229 Class nativeAncestorOf(Class cls) {
231 return nativeSuperclassOf(cls.superclass); 230 return nativeSuperclassOf(cls.superclass);
232 } 231 }
233 232
234 Map<Class, List<Class>> map = new Map<Class, List<Class>>(); 233 Map<Class, List<Class>> map = new Map<Class, List<Class>>();
235 234
236 for (Class cls in classes) { 235 for (Class cls in classes) {
237 if (cls.isNative) continue; 236 if (cls.isNative) continue;
238 Class nativeAncestor = nativeAncestorOf(cls); 237 Class nativeAncestor = nativeAncestorOf(cls);
239 if (nativeAncestor != null) { 238 if (nativeAncestor != null) {
240 map 239 map.putIfAbsent(nativeAncestor, () => <Class>[]).add(cls);
241 .putIfAbsent(nativeAncestor, () => <Class>[])
242 .add(cls);
243 } 240 }
244 } 241 }
245 return map; 242 return map;
246 } 243 }
247 244
248 bool isTrivialClass(Class cls) { 245 bool isTrivialClass(Class cls) {
249 bool needsAccessor(Field field) { 246 bool needsAccessor(Field field) {
250 return field.needsGetter || 247 return field.needsGetter ||
251 field.needsUncheckedSetter || 248 field.needsUncheckedSetter ||
252 field.needsCheckedSetter; 249 field.needsCheckedSetter;
253 } 250 }
254 251
255 return 252 return cls.methods.isEmpty &&
256 cls.methods.isEmpty &&
257 cls.isChecks.isEmpty && 253 cls.isChecks.isEmpty &&
258 cls.callStubs.isEmpty && 254 cls.callStubs.isEmpty &&
259 !cls.superclass.isMixinApplication && 255 !cls.superclass.isMixinApplication &&
260 !cls.fields.any(needsAccessor); 256 !cls.fields.any(needsAccessor);
261 } 257 }
262 258
263 void potentiallyConvertDartClosuresToJs( 259 void potentiallyConvertDartClosuresToJs(List<jsAst.Statement> statements,
264 List<jsAst.Statement> statements, 260 FunctionElement member, List<jsAst.Parameter> stubParameters) {
265 FunctionElement member,
266 List<jsAst.Parameter> stubParameters) {
267 FunctionSignature parameters = member.functionSignature; 261 FunctionSignature parameters = member.functionSignature;
268 Element converter = helpers.closureConverter; 262 Element converter = helpers.closureConverter;
269 jsAst.Expression closureConverter = 263 jsAst.Expression closureConverter =
270 emitterTask.staticFunctionAccess(converter); 264 emitterTask.staticFunctionAccess(converter);
271 parameters.forEachParameter((ParameterElement parameter) { 265 parameters.forEachParameter((ParameterElement parameter) {
272 String name = parameter.name; 266 String name = parameter.name;
273 // If [name] is not in [stubParameters], then the parameter is an optional 267 // If [name] is not in [stubParameters], then the parameter is an optional
274 // parameter that was not provided for this stub. 268 // parameter that was not provided for this stub.
275 for (jsAst.Parameter stubParameter in stubParameters) { 269 for (jsAst.Parameter stubParameter in stubParameters) {
276 if (stubParameter.name == name) { 270 if (stubParameter.name == name) {
277 DartType type = parameter.type.unaliased; 271 DartType type = parameter.type.unaliased;
278 if (type is FunctionType) { 272 if (type is FunctionType) {
279 // The parameter type is a function type either directly or through 273 // The parameter type is a function type either directly or through
280 // typedef(s). 274 // typedef(s).
281 FunctionType functionType = type; 275 FunctionType functionType = type;
282 int arity = functionType.computeArity(); 276 int arity = functionType.computeArity();
283 statements.add( 277 statements.add(js
284 js.statement('# = #(#, $arity)', 278 .statement('# = #(#, $arity)', [name, closureConverter, name]));
285 [name, closureConverter, name]));
286 break; 279 break;
287 } 280 }
288 } 281 }
289 } 282 }
290 }); 283 });
291 } 284 }
292 285
293 List<jsAst.Statement> generateParameterStubStatements( 286 List<jsAst.Statement> generateParameterStubStatements(
294 FunctionElement member, 287 FunctionElement member,
295 bool isInterceptedMethod, 288 bool isInterceptedMethod,
(...skipping 17 matching lines...) Expand all
313 jsAst.Expression receiver; 306 jsAst.Expression receiver;
314 List<jsAst.Expression> arguments; 307 List<jsAst.Expression> arguments;
315 308
316 assert(invariant(member, nativeMethods.contains(member))); 309 assert(invariant(member, nativeMethods.contains(member)));
317 // When calling a JS method, we call it with the native name, and only the 310 // When calling a JS method, we call it with the native name, and only the
318 // arguments up until the last one provided. 311 // arguments up until the last one provided.
319 target = backend.nativeData.getFixedBackendName(member); 312 target = backend.nativeData.getFixedBackendName(member);
320 313
321 if (isInterceptedMethod) { 314 if (isInterceptedMethod) {
322 receiver = argumentsBuffer[0]; 315 receiver = argumentsBuffer[0];
323 arguments = argumentsBuffer.sublist(1, 316 arguments = argumentsBuffer.sublist(
324 indexOfLastOptionalArgumentInParameters + 1); 317 1, indexOfLastOptionalArgumentInParameters + 1);
325 } else { 318 } else {
326 // Native methods that are not intercepted must be static. 319 // Native methods that are not intercepted must be static.
327 assert(invariant(member, member.isStatic)); 320 assert(invariant(member, member.isStatic));
328 arguments = argumentsBuffer.sublist(0, 321 arguments = argumentsBuffer.sublist(
329 indexOfLastOptionalArgumentInParameters + 1); 322 0, indexOfLastOptionalArgumentInParameters + 1);
330 if (backend.isJsInterop(member)) { 323 if (backend.isJsInterop(member)) {
331 // fixedBackendPath is allowed to have the form foo.bar.baz for 324 // fixedBackendPath is allowed to have the form foo.bar.baz for
332 // interop. This template is uncached to avoid possibly running out of 325 // interop. This template is uncached to avoid possibly running out of
333 // memory when Dart2Js is run in server mode. In reality the risk of 326 // memory when Dart2Js is run in server mode. In reality the risk of
334 // caching these templates causing an issue is very low as each class 327 // caching these templates causing an issue is very low as each class
335 // and library that uses typed JavaScript interop will create only 1 328 // and library that uses typed JavaScript interop will create only 1
336 // unique template. 329 // unique template.
337 receiver = js.uncachedExpressionTemplate( 330 receiver = js
338 backend.namer.fixedBackendPath(member)).instantiate([]); 331 .uncachedExpressionTemplate(backend.namer.fixedBackendPath(member))
332 .instantiate([]);
339 } else { 333 } else {
340 receiver = js('this'); 334 receiver = js('this');
341 } 335 }
342 } 336 }
343 statements.add( 337 statements
344 js.statement('return #.#(#)', [receiver, target, arguments])); 338 .add(js.statement('return #.#(#)', [receiver, target, arguments]));
345 339
346 return statements; 340 return statements;
347 } 341 }
348 342
349 bool isSupertypeOfNativeClass(ClassElement element) { 343 bool isSupertypeOfNativeClass(ClassElement element) {
350 if (backend.classesMixedIntoInterceptedClasses.contains(element)) { 344 if (backend.classesMixedIntoInterceptedClasses.contains(element)) {
351 return true; 345 return true;
352 } 346 }
353 347
354 return subtypes[element] != null; 348 return subtypes[element] != null;
355 } 349 }
356 350
357 bool requiresNativeIsCheck(Element element) { 351 bool requiresNativeIsCheck(Element element) {
358 // TODO(sra): Remove this function. It determines if a native type may 352 // TODO(sra): Remove this function. It determines if a native type may
359 // satisfy a check against [element], in which case an interceptor must be 353 // satisfy a check against [element], in which case an interceptor must be
360 // used. We should also use an interceptor if the check can't be satisfied 354 // used. We should also use an interceptor if the check can't be satisfied
361 // by a native class in case we get a native instance that tries to spoof 355 // by a native class in case we get a native instance that tries to spoof
362 // the type info. i.e the criteria for whether or not to use an interceptor 356 // the type info. i.e the criteria for whether or not to use an interceptor
363 // is whether the receiver can be native, not the type of the test. 357 // is whether the receiver can be native, not the type of the test.
364 if (element == null || !element.isClass) return false; 358 if (element == null || !element.isClass) return false;
365 ClassElement cls = element; 359 ClassElement cls = element;
366 if (backend.isNativeOrExtendsNative(cls)) return true; 360 if (backend.isNativeOrExtendsNative(cls)) return true;
367 return isSupertypeOfNativeClass(element); 361 return isSupertypeOfNativeClass(element);
368 } 362 }
369 } 363 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/model.dart ('k') | pkg/compiler/lib/src/js_emitter/native_generator.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698