diff --git a/pkg/dart2wasm/lib/closures.dart b/pkg/dart2wasm/lib/closures.dart index 1c60925f201..baa63995e69 100644 --- a/pkg/dart2wasm/lib/closures.dart +++ b/pkg/dart2wasm/lib/closures.dart @@ -203,10 +203,10 @@ class ClosureLayouter extends RecursiveVisitor { representations; // Dynamic submodules invoke closures dynamically so they use the base structs - // in all cases. Therefore, We only need one global copy of the - // ClosureRepresentation for generic and one for non-generic functions. - ClosureRepresentation? _dynamicSubmoduleRepresentation; - ClosureRepresentation? _dynamicSubmoduleGenericRepresentation; + // in all cases. Therefore, we only need one global copy of the + // ClosureRepresentation for each type parameter count. + final Map + _dynamicSubmoduleGenericRepresentations = {}; Set visitedConstants = Set.identity(); @@ -484,11 +484,7 @@ class ClosureLayouter extends RecursiveVisitor { ClosureRepresentation? getClosureRepresentation( int typeCount, int positionalCount, List names) { if (translator.dynamicModuleSupportEnabled) { - if (typeCount == 0) { - return _dynamicSubmoduleRepresentation ??= - _createRepresentation(typeCount, 0, const [], null, null, const []); - } - return _dynamicSubmoduleGenericRepresentation ??= + return _dynamicSubmoduleGenericRepresentations[typeCount] ??= _createRepresentation(typeCount, 0, const [], null, null, const []); } final representations = diff --git a/pkg/dynamic_modules/test/data/closure_instantiation/dynamic_interface.yaml b/pkg/dynamic_modules/test/data/closure_instantiation/dynamic_interface.yaml new file mode 100644 index 00000000000..988bfc2a53d --- /dev/null +++ b/pkg/dynamic_modules/test/data/closure_instantiation/dynamic_interface.yaml @@ -0,0 +1,7 @@ +# Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. +callable: + - library: 'dart:core' + - library: 'shared/shared.dart' + - library: 'package:expect/expect.dart' diff --git a/pkg/dynamic_modules/test/data/closure_instantiation/main.dart b/pkg/dynamic_modules/test/data/closure_instantiation/main.dart new file mode 100644 index 00000000000..a8dd748b8cb --- /dev/null +++ b/pkg/dynamic_modules/test/data/closure_instantiation/main.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../../common/testing.dart' as helper; +import 'package:expect/expect.dart'; + +import 'shared/shared.dart' as shared; + +void main() async { + final wrap = shared.wrap; + final wrapped = wrap(3, 'hello'); + Expect.equals(3, wrapped.$1); + Expect.equals('hello', wrapped.$2); + final dynModWrap = + await helper.load('entry1.dart') as (bool, int) Function(bool k, int v); + final dynModWrapped = dynModWrap(true, 5); + Expect.equals(true, dynModWrapped.$1); + Expect.equals(5, dynModWrapped.$2); + helper.done(); +} diff --git a/pkg/dynamic_modules/test/data/closure_instantiation/modules/entry1.dart b/pkg/dynamic_modules/test/data/closure_instantiation/modules/entry1.dart new file mode 100644 index 00000000000..1c5dab89ff2 --- /dev/null +++ b/pkg/dynamic_modules/test/data/closure_instantiation/modules/entry1.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import '../shared/shared.dart' as shared; +import 'package:expect/expect.dart'; + +@pragma('dyn-module:entry-point') +Object dynamicModuleEntrypoint() { + final wrap = shared.wrap, String>; + final wrapped = wrap([20], 'foo'); + Expect.equals(20, wrapped.$1[0]); + Expect.equals('foo', wrapped.$2); + return shared.wrap; +} diff --git a/pkg/dynamic_modules/test/data/closure_instantiation/shared/shared.dart b/pkg/dynamic_modules/test/data/closure_instantiation/shared/shared.dart new file mode 100644 index 00000000000..5b2edcf2828 --- /dev/null +++ b/pkg/dynamic_modules/test/data/closure_instantiation/shared/shared.dart @@ -0,0 +1,5 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +(K, V) wrap(K k, V v) => (k, v);