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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 861093002: Support intercepted getters, setters and index operations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Only reject instance members that need interceptors and disable a test that we do not support yet. Created 5 years, 10 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_backend/codegen/codegen.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 // IrNodes are kept in a separate library to have precise control over their 5 // IrNodes are kept in a separate library to have precise control over their
6 // dependencies on other parts of the system. 6 // dependencies on other parts of the system.
7 library dart2js.ir_nodes; 7 library dart2js.ir_nodes;
8 8
9 import '../constants/expressions.dart'; 9 import '../constants/expressions.dart';
10 import '../constants/values.dart' as values show ConstantValue; 10 import '../constants/values.dart' as values show ConstantValue;
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 InvokeStatic(this.target, this.selector, Continuation cont, 213 InvokeStatic(this.target, this.selector, Continuation cont,
214 List<Primitive> args) 214 List<Primitive> args)
215 : continuation = new Reference<Continuation>(cont), 215 : continuation = new Reference<Continuation>(cont),
216 arguments = _referenceList(args) { 216 arguments = _referenceList(args) {
217 assert(target is ErroneousElement || selector.name == target.name); 217 assert(target is ErroneousElement || selector.name == target.name);
218 } 218 }
219 219
220 accept(Visitor visitor) => visitor.visitInvokeStatic(this); 220 accept(Visitor visitor) => visitor.visitInvokeStatic(this);
221 } 221 }
222 222
223 /// A [CallingConvention] codifies how arguments are matched to parameters when
224 /// emitting code for a function call.
225 class CallingConvention {
226 final String name;
227 const CallingConvention(this.name);
228 /// The normal way of calling a Dart function: Positional arguments are
229 /// matched with (mandatory and optional) positionals parameters from left to
230 /// right and named arguments are matched by name.
231 static const CallingConvention DART = const CallingConvention("Dart call");
232 /// Intercepted calls have an additional first argument that is the actual
233 /// receiver of the call. See the documentation of [Interceptor] for more
234 /// information.
235 static const CallingConvention JS_INTERCEPTED =
236 const CallingConvention("intercepted JavaScript call");
237 }
238
223 /// Invoke a method, operator, getter, setter, or index getter/setter. 239 /// Invoke a method, operator, getter, setter, or index getter/setter.
224 /// Converting a method to a function object is treated as a getter invocation. 240 /// Converting a method to a function object is treated as a getter invocation.
225 class InvokeMethod extends Expression implements Invoke { 241 class InvokeMethod extends Expression implements Invoke {
226 Reference<Primitive> receiver; 242 Reference<Primitive> receiver;
227 final Selector selector; 243 Selector selector;
244 CallingConvention callingConvention;
228 final Reference<Continuation> continuation; 245 final Reference<Continuation> continuation;
229 final List<Reference<Primitive>> arguments; 246 final List<Reference<Primitive>> arguments;
230 247
231 InvokeMethod(Primitive receiver, 248 InvokeMethod(Primitive receiver,
232 Selector selector, 249 Selector selector,
233 Continuation cont, 250 Continuation continuation,
234 List<Primitive> args) 251 List<Primitive> arguments)
235 : this.internal(new Reference<Primitive>(receiver), 252 : this.internal(new Reference<Primitive>(receiver),
236 selector, 253 selector,
237 new Reference<Continuation>(cont), 254 new Reference<Continuation>(continuation),
238 _referenceList(args)); 255 _referenceList(arguments));
239 256
240 InvokeMethod.internal(this.receiver, 257 InvokeMethod.internal(this.receiver,
241 this.selector, 258 this.selector,
242 this.continuation, 259 this.continuation,
243 this.arguments) { 260 this.arguments,
244 assert(selector != null); 261 [this.callingConvention = CallingConvention.DART]) {
245 assert(selector.kind == SelectorKind.CALL || 262 assert(isValid);
246 selector.kind == SelectorKind.OPERATOR ||
247 (selector.kind == SelectorKind.GETTER && arguments.isEmpty) ||
248 (selector.kind == SelectorKind.SETTER && arguments.length == 1) ||
249 (selector.kind == SelectorKind.INDEX && arguments.length == 1) ||
250 (selector.kind == SelectorKind.INDEX && arguments.length == 2));
251 } 263 }
252 264
253 bool get isIntercepted => receiver.definition is Interceptor; 265 /// Returns whether the arguments match the selector under the given calling
266 /// convention.
267 ///
268 /// This check is designed to be used in an assert, as it also checks that the
269 /// selector, arguments, and calling convention have meaningful values.
270 bool get isValid {
271 if (selector == null || callingConvention == null) return false;
272 if (callingConvention != CallingConvention.DART &&
273 callingConvention != CallingConvention.JS_INTERCEPTED) {
274 return false;
275 }
276 int numberOfArguments =
277 callingConvention == CallingConvention.JS_INTERCEPTED
278 ? arguments.length - 1
279 : arguments.length;
280 return selector.kind == SelectorKind.CALL ||
281 selector.kind == SelectorKind.OPERATOR ||
282 (selector.kind == SelectorKind.GETTER && numberOfArguments == 0) ||
283 (selector.kind == SelectorKind.SETTER && numberOfArguments == 1) ||
284 (selector.kind == SelectorKind.INDEX && numberOfArguments == 1) ||
285 (selector.kind == SelectorKind.INDEX && numberOfArguments == 2);
286 }
254 287
255 accept(Visitor visitor) => visitor.visitInvokeMethod(this); 288 accept(Visitor visitor) => visitor.visitInvokeMethod(this);
256 } 289 }
257 290
258 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. 291 /// Invoke [target] on [receiver], bypassing dispatch and override semantics.
259 /// 292 ///
260 /// That is, if [receiver] is an instance of a class that overrides [target] 293 /// That is, if [receiver] is an instance of a class that overrides [target]
261 /// with a different implementation, the overriding implementation is bypassed 294 /// with a different implementation, the overriding implementation is bypassed
262 /// and [target]'s implementation is invoked. 295 /// and [target]'s implementation is invoked.
263 /// 296 ///
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 1391
1359 void visitIdentical(Identical node) { 1392 void visitIdentical(Identical node) {
1360 visitReference(node.left); 1393 visitReference(node.left);
1361 visitReference(node.right); 1394 visitReference(node.right);
1362 } 1395 }
1363 1396
1364 void visitInterceptor(Interceptor node) { 1397 void visitInterceptor(Interceptor node) {
1365 visitReference(node.input); 1398 visitReference(node.input);
1366 } 1399 }
1367 } 1400 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_backend/codegen/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698