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

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

Issue 14049010: Take noSuchMethod into account when computing the potential targets of a call. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: 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 universe; 5 part of universe;
6 6
7 // TODO(kasperl): This actually holds getters and setters just fine 7 // TODO(kasperl): This actually holds getters and setters just fine
8 // too and stricly they aren't functions. Maybe this needs a better 8 // too and stricly they aren't functions. Maybe this needs a better
9 // name -- something like ElementSet seems a bit too generic. 9 // name -- something like ElementSet seems a bit too generic.
10 class FunctionSet { 10 class FunctionSet {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 : false; 44 : false;
45 } 45 }
46 46
47 /** 47 /**
48 * Returns an object that allows iterating over all the functions 48 * Returns an object that allows iterating over all the functions
49 * that may be invoked with the given [selector]. 49 * that may be invoked with the given [selector].
50 */ 50 */
51 Iterable<Element> filter(Selector selector) { 51 Iterable<Element> filter(Selector selector) {
52 SourceString name = selector.name; 52 SourceString name = selector.name;
53 FunctionSetNode node = nodes[name]; 53 FunctionSetNode node = nodes[name];
54 return (node != null) 54 FunctionSetNode noSuchMethods = nodes[Compiler.NO_SUCH_METHOD];
55 ? node.query(selector, compiler).functions 55 if (node != null) {
56 : const <Element>[]; 56 return node.query(selector, compiler, noSuchMethods).functions;
57 }
58 // If there is no method that matches [selector] we know we can
59 // only hit [:noSuchMethod:].
60 if (noSuchMethods == null) return const <Element>[];
61 selector = (selector.mask == null)
62 ? compiler.noSuchMethodSelector
63 : new TypedSelector(selector.mask, compiler.noSuchMethodSelector);
64
65 return noSuchMethods.query(selector, compiler, null).functions;
57 } 66 }
58 67
59 void forEach(Function action) { 68 void forEach(Function action) {
60 nodes.forEach((SourceString name, FunctionSetNode node) { 69 nodes.forEach((SourceString name, FunctionSetNode node) {
61 node.forEach(action); 70 node.forEach(action);
62 }); 71 });
63 } 72 }
64 } 73 }
65 74
66 75
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 126
118 bool contains(Element element) { 127 bool contains(Element element) {
119 assert(element.name == name); 128 assert(element.name == name);
120 return elements.contains(element); 129 return elements.contains(element);
121 } 130 }
122 131
123 void forEach(Function action) { 132 void forEach(Function action) {
124 elements.forEach(action); 133 elements.forEach(action);
125 } 134 }
126 135
127 FunctionSetQuery query(Selector selector, Compiler compiler) { 136 TypeMask getNonNullTypeMaskOfSelector(Selector selector, Compiler compiler) {
137 // TODO(ngeoffray): We should probably change untyped selector
138 // to always be a subclass of Object.
139 return selector.mask != null
140 ? selector.mask
141 : new TypeMask.subclass(compiler.objectClass.rawType);
142 }
143
144 FunctionSetQuery query(Selector selector,
145 Compiler compiler,
146 FunctionSetNode noSuchMethods) {
128 assert(selector.name == name); 147 assert(selector.name == name);
129 FunctionSetQuery result = cache[selector]; 148 FunctionSetQuery result = cache[selector];
130 if (result != null) return result; 149 if (result != null) return result;
131 List<Element> functions; 150 List<Element> functions;
132 for (Element element in elements) { 151 for (Element element in elements) {
133 if (selector.appliesUnnamed(element, compiler)) { 152 if (selector.appliesUnnamed(element, compiler)) {
134 if (functions == null) { 153 if (functions == null) {
135 // Defer the allocation of the functions list until we are 154 // Defer the allocation of the functions list until we are
136 // sure we need it. This allows us to return immutable empty 155 // sure we need it. This allows us to return immutable empty
137 // lists when the filtering produced no results. 156 // lists when the filtering produced no results.
138 functions = <Element>[]; 157 functions = <Element>[];
139 } 158 }
140 functions.add(element); 159 functions.add(element);
141 } 160 }
142 } 161 }
162
163 TypeMask mask = getNonNullTypeMaskOfSelector(selector, compiler);
164 // If we cannot ensure a method will be found at runtime, we also
165 // add [noSuchMethod] implementations that apply to [mask] as
166 // potential targets.
167 if (noSuchMethods != null && !mask.willHit(selector, compiler)) {
168 FunctionSetQuery noSuchMethodQuery = noSuchMethods.query(
169 new TypedSelector(mask, compiler.noSuchMethodSelector),
170 compiler,
171 null);
172 if (!noSuchMethodQuery.functions.isEmpty) {
173 if (functions == null) {
174 functions = new List<Element>.from(noSuchMethodQuery.functions);
175 } else {
176 functions.addAll(noSuchMethodQuery.functions);
177 }
178 }
179 }
143 cache[selector] = result = (functions != null) 180 cache[selector] = result = (functions != null)
144 ? newQuery(functions, selector, compiler) 181 ? newQuery(functions, selector, compiler)
145 : const FunctionSetQuery(const <Element>[]); 182 : const FunctionSetQuery(const <Element>[]);
146 return result; 183 return result;
147 } 184 }
148 185
149 FunctionSetQuery newQuery(List<Element> functions, 186 FunctionSetQuery newQuery(List<Element> functions,
150 Selector selector, 187 Selector selector,
151 Compiler compiler) { 188 Compiler compiler) {
152 return new FunctionSetQuery(functions); 189 return new FunctionSetQuery(functions);
153 } 190 }
154 } 191 }
155 192
156 class FunctionSetQuery { 193 class FunctionSetQuery {
157 final List<Element> functions; 194 final List<Element> functions;
158 const FunctionSetQuery(this.functions); 195 const FunctionSetQuery(this.functions);
159 } 196 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698