[dart2wasm] Fix for tearoffs in allowInterop.

Change-Id: Ic753bb22af345e4825f2a142fa262504a562e7c4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/260283
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
This commit is contained in:
Joshua Litt 2022-09-22 03:04:17 +00:00 committed by Commit Bot
parent e03170035a
commit fea406591e
2 changed files with 104 additions and 0 deletions

View file

@ -274,6 +274,9 @@ class JsUtilWasmOptimizer extends Transformer {
callbackTarget.function.positionalParameters[i].initializer;
} else if (argument is FunctionExpression) {
initializer = argument.function.positionalParameters[i].initializer;
} else if (argument is InstanceTearOff) {
initializer = argument.interfaceTargetReference.asProcedure.function
.positionalParameters[i].initializer;
} else {
throw 'Cannot pass default arguments.';
}

View file

@ -155,6 +155,30 @@ void staticInteropCallbackTest() {
Expect.equals('foobar', helper.doSumTwoOptionalCNonNull('foo', 'bar'));
}
typedef NoArgsFun = String Function();
typedef OneArgFun = String Function(String arg);
typedef OnePositionalAndOneOptionalArgsFun = String Function(String arg,
[String arg2]);
typedef TwoPositionalArgsFun = String Function([String arg, String arg2]);
class TornOffClass {
String noArgs() {
return 'foo';
}
String oneArg(String arg) {
return arg;
}
String onePositionalAndOneOptionalArgs(String arg, [String arg2 = 'bar']) {
return arg + arg2;
}
String twoPositionalArgs([String arg = 'foo', String? arg2]) {
return arg + (arg2 ?? '');
}
}
void allowInteropCallbackTest() {
eval(r'''
globalThis.doSum1 = function(summer) {
@ -193,6 +217,26 @@ void allowInteropCallbackTest() {
globalThis.doSumTwoOptionalCNonNull = function(a, b) {
return summer(a, b);
}
// tear off cases
globalThis.tearOffNoArgs = function (f) {
return f();
}
globalThis.tearOffOneArg = function (f) {
return f('foo');
}
globalThis.tearOffOnePositionalAndOneOptionalArgsA = function (f) {
return f('foo');
}
globalThis.tearOffOnePositionalAndOneOptionalArgsB = function (f) {
return f('foo', 'baz');
}
globalThis.tearOffTwoPositionalArgsA = function (f) {
return f('foo');
}
globalThis.tearOffTwoPositionalArgsB = function (f) {
return f('foo', 'baz');
}
''');
// General
@ -266,6 +310,63 @@ void allowInteropCallbackTest() {
Expect.equals('foobar',
callMethod(globalThis, 'doSumTwoOptionalC', ['foo', 'bar']).toString());
}
// Tear off cases
// No args.
{
final t = TornOffClass();
final interopCallback = allowInterop<NoArgsFun>(t.noArgs);
Expect.equals(
'foo', callMethod(globalThis, 'tearOffNoArgs', [interopCallback]));
}
// One arg.
{
final t = TornOffClass();
final interopCallback = allowInterop<OneArgFun>(t.oneArg);
Expect.equals(
'foo', callMethod(globalThis, 'tearOffOneArg', [interopCallback]));
}
// One positional and one optional case A.
{
final t = TornOffClass();
final interopCallback = allowInterop<OnePositionalAndOneOptionalArgsFun>(
t.onePositionalAndOneOptionalArgs);
Expect.equals(
'foobar',
callMethod(globalThis, 'tearOffOnePositionalAndOneOptionalArgsA',
[interopCallback]));
}
// One positional and one optional case B.
{
final t = TornOffClass();
final interopCallback = allowInterop<OnePositionalAndOneOptionalArgsFun>(
t.onePositionalAndOneOptionalArgs);
Expect.equals(
'foobaz',
callMethod(globalThis, 'tearOffOnePositionalAndOneOptionalArgsB',
[interopCallback]));
}
// Two positional case A.
{
final t = TornOffClass();
final interopCallback =
allowInterop<TwoPositionalArgsFun>(t.twoPositionalArgs);
Expect.equals('foo',
callMethod(globalThis, 'tearOffTwoPositionalArgsA', [interopCallback]));
}
// Two positional case B.
{
final t = TornOffClass();
final interopCallback =
allowInterop<TwoPositionalArgsFun>(t.twoPositionalArgs);
Expect.equals('foobaz',
callMethod(globalThis, 'tearOffTwoPositionalArgsB', [interopCallback]));
}
}
void main() {