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

Side by Side Diff: sdk/lib/_internal/compiler/js_lib/interceptors.dart

Issue 1181063005: Fix for issue 23432 - Get the correct receiver in noSuchMethod stubs. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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 library _interceptors; 5 library _interceptors;
6 6
7 import 'dart:_js_embedded_names' show 7 import 'dart:_js_embedded_names' show
8 DISPATCH_PROPERTY_NAME, 8 DISPATCH_PROPERTY_NAME,
9 TYPE_TO_INTERCEPTOR_MAP; 9 TYPE_TO_INTERCEPTOR_MAP;
10 10
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 * The code `r.foo(a)` is compiled to `getInterceptor(r).foo$1(r, a)`. The 242 * The code `r.foo(a)` is compiled to `getInterceptor(r).foo$1(r, a)`. The
243 * value returned by [getInterceptor] holds the methods separately from the 243 * value returned by [getInterceptor] holds the methods separately from the
244 * state of the instance. The compiler converts the methods on an interceptor 244 * state of the instance. The compiler converts the methods on an interceptor
245 * to take the Dart `this` argument as an explicit `receiver` argument. The 245 * to take the Dart `this` argument as an explicit `receiver` argument. The
246 * JavaScript `this` parameter is bound to the interceptor. 246 * JavaScript `this` parameter is bound to the interceptor.
247 * 247 *
248 * In order to have uniform call sites, if a method is defined on an 248 * In order to have uniform call sites, if a method is defined on an
249 * interceptor, methods of that name on plain unintercepted classes also use the 249 * interceptor, methods of that name on plain unintercepted classes also use the
250 * interceptor calling convention. The plain classes are _self-interceptors_, 250 * interceptor calling convention. The plain classes are _self-interceptors_,
251 * and for them, `getInterceptor(r)` returns `r`. Methods on plain 251 * and for them, `getInterceptor(r)` returns `r`. Methods on plain
252 * unintercepted classes have a redundant `receiver` argument and should ignore 252 * unintercepted classes have a redundant `receiver` argument and, to enable
253 * it in favour of `this`. 253 * some optimizations, must ignore `receiver` in favour of `this`.
254 * 254 *
255 * In the case of mixins, a method may be placed on both an intercepted class 255 * In the case of mixins, a method may be placed on both an intercepted class
256 * and an unintercepted class. In this case, the method must use the `receiver` 256 * and an unintercepted class. In this case, the method must use the `receiver`
257 * parameter. 257 * parameter.
258 * 258 *
259 * 259 *
260 * There are various optimizations of the general call pattern. 260 * There are various optimizations of the general call pattern.
261 * 261 *
262 * When the interceptor can be statically determined, it can be used directly: 262 * When the interceptor can be statically determined, it can be used directly:
263 * 263 *
(...skipping 22 matching lines...) Expand all
286 */ 286 */
287 abstract class Interceptor { 287 abstract class Interceptor {
288 const Interceptor(); 288 const Interceptor();
289 289
290 bool operator ==(other) => identical(this, other); 290 bool operator ==(other) => identical(this, other);
291 291
292 int get hashCode => Primitives.objectHashCode(this); 292 int get hashCode => Primitives.objectHashCode(this);
293 293
294 String toString() => Primitives.objectToHumanReadableString(this); 294 String toString() => Primitives.objectToHumanReadableString(this);
295 295
296 // [Interceptor.noSuchMethod] is identical to [Object.noSuchMethod]. However,
297 // each copy is compiled differently. The presence of the method on an
298 // Interceptor class forces [noSuchMethod] to use interceptor calling
299 // convention. In the [Interceptor] version, `this` is the explicit receiver
300 // argument. In the [Object] version, as Object is not an intercepted class,
301 // `this` is the JavaScript receiver, and the explicit receiver is ignored.
302 // The noSuchMethod stubs for selectors that use the interceptor calling
303 // convention do not know the calling convention and forward `this` and
304 // `receiver` to one of these noSuchMethod implementations which selects the
305 // correct Dart receiver.
306 //
307 // We don't allow [noSuchMethod] on intercepted classes (that would force all
308 // calls to use interceptor calling convention). If we did allow it, the
309 // interceptor context would select the correct `this`.
296 dynamic noSuchMethod(Invocation invocation) { 310 dynamic noSuchMethod(Invocation invocation) {
297 throw new NoSuchMethodError( 311 throw new NoSuchMethodError(
298 this, 312 this,
299 invocation.memberName, 313 invocation.memberName,
300 invocation.positionalArguments, 314 invocation.positionalArguments,
301 invocation.namedArguments); 315 invocation.namedArguments);
302 } 316 }
303 317
304 Type get runtimeType => getRuntimeType(this); 318 Type get runtimeType => getRuntimeType(this);
305 } 319 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 * Interceptor for unclassified JavaScript objects, typically objects with a 415 * Interceptor for unclassified JavaScript objects, typically objects with a
402 * non-trivial prototype chain. 416 * non-trivial prototype chain.
403 * 417 *
404 * This class also serves as a fallback for unknown JavaScript exceptions. 418 * This class also serves as a fallback for unknown JavaScript exceptions.
405 */ 419 */
406 class UnknownJavaScriptObject extends JavaScriptObject { 420 class UnknownJavaScriptObject extends JavaScriptObject {
407 const UnknownJavaScriptObject(); 421 const UnknownJavaScriptObject();
408 422
409 String toString() => JS('String', 'String(#)', this); 423 String toString() => JS('String', 'String(#)', this);
410 } 424 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698