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

Unified Diff: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart

Issue 2873073002: fix #29585, implement equality for tearoffs (Closed)
Patch Set: merged Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index 13916d4d8ee6cd9c53cda62a387e8f6c45932a04..bfcf9d6c7d006ec4d6c0c2d00a624e0a6182d149 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -29,6 +29,57 @@ class InvocationImpl extends Invocation {
}
}
+/// Given an object and a method name, tear off the method.
+/// Sets the runtime type of the torn off method appropriately,
+/// and also binds the object.
+///
+/// If the optional `f` argument is passed in, it will be used as the method.
+/// This supports cases like `super.foo` where we need to tear off the method
+/// from the superclass, not from the `obj` directly.
+/// TODO(leafp): Consider caching the tearoff on the object?
+bind(obj, name, f) {
+ if (f == null) f = JS('', '#[#]', obj, name);
+
+ // TODO(jmesserly): it would be nice to do this lazily, but JS interop seems
+ // to require us to be eager (the test below).
+ var sig = getMethodType(getType(obj), name);
+
+ // JS interop case: do not bind this for compatibility with the dart2js
+ // implementation where we cannot bind this reliably here until we trust
+ // types more.
+ if (sig == null) return f;
+
+ f = JS('', '#.bind(#)', f, obj);
+ JS(
+ '',
+ r'''#[dartx["=="]] = function boundMethodEquals(other) {
+ return other[#] === this[#] && other[#] === this[#];
+ }''',
+ f,
+ _boundMethodTarget,
+ _boundMethodTarget,
+ _boundMethodName,
+ _boundMethodName);
+ JS('', '#[#] = #', f, _boundMethodTarget, obj);
+ JS('', '#[#] = #', f, _boundMethodName, name);
+ tag(f, sig);
+ return f;
+}
+
+final _boundMethodTarget = JS('', 'Symbol("_boundMethodTarget")');
+final _boundMethodName = JS('', 'Symbol("_boundMethodName")');
+
+/// Instantiate a generic method.
+///
+/// We need to apply the type arguments both to the function, as well as its
+/// associated function type.
+gbind(f, @rest typeArgs) {
+ var result = JS('', '#.apply(null, #)', f, typeArgs);
+ var sig = JS('', '#.instantiate(#)', _getRuntimeType(f), typeArgs);
+ tag(result, sig);
+ return result;
+}
+
// Warning: dload, dput, and dsend assume they are never called on methods
// implemented by the Object base class as those methods can always be
// statically resolved.
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart ('k') | tests/language_strong/tearoff_dynamic_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698