Tighten call conventions in allowInterop

Towards #33134

Functions called through allowInterop or allowInteropCaptureThis wrappers will
use the `dart.dcall` code path which checks argument counts and types. This will
make these calls stricter to match dart2js semantics.

In the long term we want to make dart2js accept _extra_ arguments, at which
point we'll also want to make DDK loose in the same way. For now we want DDC
to be strict.

Change-Id: Ibf1dabf141273229770f8328f9ca7bfb9f4fb5db
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/113754
Commit-Queue: Nate Bosch <nbosch@google.com>
Auto-Submit: Nate Bosch <nbosch@google.com>
Reviewed-by: Vijay Menon <vsm@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
Nate Bosch 2019-09-07 01:30:05 +00:00 committed by commit-bot@chromium.org
parent c0f49b05dd
commit cff9c587f4
2 changed files with 28 additions and 9 deletions

View file

@ -191,6 +191,15 @@ well as a potential crash of our AOT compiler.
[37551]: https://github.com/dart-lang/sdk/issues/37551
[35121]: https://github.com/dart-lang/sdk/issues/35121
### Dart Dev Compiler (DDC)
Callbacks passed to JS and wrapped with `allowInterop` or
`allowInteropCaptureThis` are now strict about argument counts and argument
types. This may mean that tests which were previously passing and relying on
loose argument checking (too many or too few arguments, or arguments with too
specific types like `List<Something>` instead of `List<dynamic>`) may start
failing. This changes makes DDC behave more like dart2js with the default flags.
## 2.4.0 - 2019-06-27
### Core libraries

View file

@ -541,9 +541,7 @@ Object _putIfAbsent(weakMap, o, getValue(o)) {
return value;
}
// The allowInterop method is a no-op in Dart Dev Compiler.
// TODO(jacobr): tag methods so we can throw if a Dart method is passed to
// JavaScript using the new interop without calling allowInterop.
Expando<Function> _interopExpando = Expando<Function>();
/// Returns a wrapper around function [f] that can be called from JavaScript
/// using the package:js Dart-JavaScript interop.
@ -556,7 +554,20 @@ Object _putIfAbsent(weakMap, o, getValue(o)) {
/// JavaScript. We may remove the need to call this method completely in the
/// future if Dart2Js is refactored so that its function calling conventions
/// are more compatible with JavaScript.
F allowInterop<F extends Function>(F f) => f;
F allowInterop<F extends Function>(F f) {
var ret = _interopExpando[f];
if (ret == null) {
ret = JS(
'',
'function (...args) {'
' return #(#, args);'
'}',
dart.dcall,
f);
_interopExpando[f] = ret;
}
return ret;
}
Expando<Function> _interopCaptureThisExpando = Expando<Function>();
@ -571,13 +582,12 @@ Function allowInteropCaptureThis(Function f) {
if (ret == null) {
ret = JS(
'',
'function(/*...arguments*/) {'
'function(...arguments) {'
' let args = [this];'
' for (let arg of arguments) {'
' args.push(arg);'
' }'
' return #(...args);'
' args.push.apply(args, arguments);'
' return #(#, args);'
'}',
dart.dcall,
f);
_interopCaptureThisExpando[f] = ret;
}