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

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

Issue 12334070: Support runtime check of function types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: New check encoding Created 7 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 | 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 dart2js; 5 part of dart2js;
6 6
7 class EnqueueTask extends CompilerTask { 7 class EnqueueTask extends CompilerTask {
8 final ResolutionEnqueuer resolution; 8 final ResolutionEnqueuer resolution;
9 final CodegenEnqueuer codegen; 9 final CodegenEnqueuer codegen;
10 10
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 if (!addElementToWorkList(element, elements)) return; 62 if (!addElementToWorkList(element, elements)) return;
63 63
64 // Enable runtime type support if we discover a getter called runtimeType. 64 // Enable runtime type support if we discover a getter called runtimeType.
65 // We have to enable runtime type before hitting the codegen, so 65 // We have to enable runtime type before hitting the codegen, so
66 // that constructors know whether they need to generate code for 66 // that constructors know whether they need to generate code for
67 // runtime type. 67 // runtime type.
68 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) { 68 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) {
69 compiler.enabledRuntimeType = true; 69 compiler.enabledRuntimeType = true;
70 // TODO(ahe): Record precise dependency here. 70 // TODO(ahe): Record precise dependency here.
71 compiler.backend.registerRuntimeType(compiler.globalDependencies); 71 compiler.backend.registerRuntimeType(this, compiler.globalDependencies);
72 } else if (element == compiler.functionApplyMethod) { 72 } else if (element == compiler.functionApplyMethod) {
73 compiler.enabledFunctionApply = true; 73 compiler.enabledFunctionApply = true;
74 } else if (element == compiler.invokeOnMethod) { 74 } else if (element == compiler.invokeOnMethod) {
75 compiler.enabledInvokeOn = true; 75 compiler.enabledInvokeOn = true;
76 } 76 }
77 77
78 nativeEnqueuer.registerElement(element); 78 nativeEnqueuer.registerElement(element);
79 } 79 }
80 80
81 /** 81 /**
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // enclosing class, since the metadata has not been parsed yet. 143 // enclosing class, since the metadata has not been parsed yet.
144 if (!member.enclosingElement.isNative()) return; 144 if (!member.enclosingElement.isNative()) return;
145 } 145 }
146 146
147 String memberName = member.name.slowToString(); 147 String memberName = member.name.slowToString();
148 148
149 if (member.kind == ElementKind.FUNCTION) { 149 if (member.kind == ElementKind.FUNCTION) {
150 if (member.name == Compiler.NO_SUCH_METHOD) { 150 if (member.name == Compiler.NO_SUCH_METHOD) {
151 enableNoSuchMethod(member); 151 enableNoSuchMethod(member);
152 } 152 }
153 if (member.name == Compiler.CALL_OPERATOR_NAME) {
154 if (!cls.typeVariables.isEmpty) {
karlklose 2013/03/22 13:17:46 use '&&'. Consider storing '!cls.typeVariables.is
Johnni Winther 2013/06/21 12:19:14 Done. '!cls.typeVariables.isEmpty' is only used on
155 registerGenericCallMethod(member, compiler.globalDependencies);
156 }
157 }
153 if (universe.hasInvocation(member, compiler)) { 158 if (universe.hasInvocation(member, compiler)) {
154 return addToWorkList(member); 159 return addToWorkList(member);
155 } 160 }
156 // If there is a property access with the same name as a method we 161 // If there is a property access with the same name as a method we
157 // need to emit the method. 162 // need to emit the method.
158 if (universe.hasInvokedGetter(member, compiler)) { 163 if (universe.hasInvokedGetter(member, compiler)) {
164 if (!cls.typeVariables.isEmpty) {
165 registerGenericClosure(member, compiler.globalDependencies);
166 }
159 // We will emit a closure, so make sure the closure class is 167 // We will emit a closure, so make sure the closure class is
160 // generated. 168 // generated.
161 compiler.closureClass.ensureResolved(compiler); 169 compiler.closureClass.ensureResolved(compiler);
162 registerInstantiatedClass(compiler.closureClass, 170 registerInstantiatedClass(compiler.closureClass,
163 // Precise dependency is not important here. 171 // Precise dependency is not important here.
164 compiler.globalDependencies); 172 compiler.globalDependencies);
165 return addToWorkList(member); 173 return addToWorkList(member);
166 } 174 }
167 } else if (member.kind == ElementKind.GETTER) { 175 } else if (member.kind == ElementKind.GETTER) {
168 if (universe.hasInvokedGetter(member, compiler)) { 176 if (universe.hasInvokedGetter(member, compiler)) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 void registerInvokedSetter(SourceString setterName, Selector selector) { 272 void registerInvokedSetter(SourceString setterName, Selector selector) {
265 task.measure(() { 273 task.measure(() {
266 registerNewSelector(setterName, selector, universe.invokedSetters); 274 registerNewSelector(setterName, selector, universe.invokedSetters);
267 }); 275 });
268 } 276 }
269 277
270 processInstanceMembers(SourceString n, bool f(Element e)) { 278 processInstanceMembers(SourceString n, bool f(Element e)) {
271 String memberName = n.slowToString(); 279 String memberName = n.slowToString();
272 Link<Element> members = instanceMembersByName[memberName]; 280 Link<Element> members = instanceMembersByName[memberName];
273 if (members != null) { 281 if (members != null) {
282 instanceMembersByName[memberName] = const Link<Element>();
karlklose 2013/03/22 13:17:46 Could you add a comment why you do this?
Johnni Winther 2013/06/21 12:19:14 Done.
274 LinkBuilder<Element> remaining = new LinkBuilder<Element>(); 283 LinkBuilder<Element> remaining = new LinkBuilder<Element>();
275 for (; !members.isEmpty; members = members.tail) { 284 for (; !members.isEmpty; members = members.tail) {
276 if (!f(members.head)) remaining.addLast(members.head); 285 if (!f(members.head)) remaining.addLast(members.head);
277 } 286 }
278 instanceMembersByName[memberName] = remaining.toLink(); 287 instanceMembersByName[memberName] =
288 remaining.toLink(instanceMembersByName[memberName]);
279 } 289 }
280 } 290 }
281 291
282 void handleUnseenSelector(SourceString methodName, Selector selector) { 292 void handleUnseenSelector(SourceString methodName, Selector selector) {
283 processInstanceMembers(methodName, (Element member) { 293 processInstanceMembers(methodName, (Element member) {
284 if (selector.appliesUnnamed(member, compiler)) { 294 if (selector.appliesUnnamed(member, compiler)) {
295 if (member.isFunction() && selector.isGetter()) {
296 if (!member.getEnclosingClass().typeVariables.isEmpty) {
297 registerGenericClosure(member, compiler.globalDependencies);
298 }
299 }
285 if (member.isField() && member.enclosingElement.isNative()) { 300 if (member.isField() && member.enclosingElement.isNative()) {
286 if (selector.isGetter() || selector.isCall()) { 301 if (selector.isGetter() || selector.isCall()) {
287 nativeEnqueuer.registerFieldLoad(member); 302 nativeEnqueuer.registerFieldLoad(member);
288 // We have to also handle storing to the field because we only get 303 // We have to also handle storing to the field because we only get
289 // one look at each member and there might be a store we have not 304 // one look at each member and there might be a store we have not
290 // seen yet. 305 // seen yet.
291 // TODO(sra): Process fields for storing separately. 306 // TODO(sra): Process fields for storing separately.
292 nativeEnqueuer.registerFieldStore(member); 307 nativeEnqueuer.registerFieldStore(member);
293 } else { 308 } else {
294 nativeEnqueuer.registerFieldStore(member); 309 nativeEnqueuer.registerFieldStore(member);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 385
371 void registerFieldGetter(Element element) { 386 void registerFieldGetter(Element element) {
372 universe.fieldGetters.add(element); 387 universe.fieldGetters.add(element);
373 } 388 }
374 389
375 void registerFieldSetter(Element element) { 390 void registerFieldSetter(Element element) {
376 universe.fieldSetters.add(element); 391 universe.fieldSetters.add(element);
377 } 392 }
378 393
379 void registerIsCheck(DartType type, TreeElements elements) { 394 void registerIsCheck(DartType type, TreeElements elements) {
395 type = type.unalias(compiler);
380 // Even in checked mode, type annotations for return type and argument 396 // Even in checked mode, type annotations for return type and argument
381 // types do not imply type checks, so there should never be a check 397 // types do not imply type checks, so there should never be a check
382 // against the type variable of a typedef. 398 // against the type variable of a typedef.
383 assert(type.kind != TypeKind.TYPE_VARIABLE || 399 assert(type.kind != TypeKind.TYPE_VARIABLE ||
384 !type.element.enclosingElement.isTypedef()); 400 !type.element.enclosingElement.isTypedef());
385 universe.isChecks.add(type); 401 universe.isChecks.add(type);
386 compiler.backend.registerIsCheck(type, this, elements); 402 compiler.backend.registerIsCheck(type, this, elements);
387 } 403 }
388 404
389 void registerAsCheck(DartType type, TreeElements elements) { 405 void registerAsCheck(DartType type, TreeElements elements) {
390 registerIsCheck(type, elements); 406 registerIsCheck(type, elements);
391 compiler.backend.registerAsCheck(type, elements); 407 compiler.backend.registerAsCheck(type, elements);
392 } 408 }
393 409
410 void registerGenericCallMethod(Element element, TreeElements elements) {
411 compiler.backend.registerGenericCallMethod(element, this, elements);
412 universe.genericCallMethods.add(element);
413 }
414
415 void registerGenericClosure(Element element, TreeElements elements) {
416 compiler.backend.registerGenericClosure(element, this, elements);
417 universe.closurizedGenericMembers.add(element);
418 }
419
394 void forEach(f(WorkItem work)); 420 void forEach(f(WorkItem work));
395 421
396 void logSummary(log(message)) { 422 void logSummary(log(message)) {
397 _logSpecificSummary(log); 423 _logSpecificSummary(log);
398 nativeEnqueuer.logSummary(log); 424 nativeEnqueuer.logSummary(log);
399 } 425 }
400 426
401 /// Log summary specific to the concrete enqueuer. 427 /// Log summary specific to the concrete enqueuer.
402 void _logSpecificSummary(log(message)); 428 void _logSpecificSummary(log(message));
403 429
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 while(!queue.isEmpty) { 588 while(!queue.isEmpty) {
563 // TODO(johnniwinther): Find an optimal process order for codegen. 589 // TODO(johnniwinther): Find an optimal process order for codegen.
564 f(queue.removeLast()); 590 f(queue.removeLast());
565 } 591 }
566 } 592 }
567 593
568 void _logSpecificSummary(log(message)) { 594 void _logSpecificSummary(log(message)) {
569 log('Compiled ${generatedCode.length} methods.'); 595 log('Compiled ${generatedCode.length} methods.');
570 } 596 }
571 } 597 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698