From e3e82c95cb3782515e5775bd8da170fd6771a723 Mon Sep 17 00:00:00 2001 From: Nate Biggs Date: Fri, 23 May 2025 15:37:33 -0700 Subject: [PATCH] [dart2wasm] Skip constructor entrypoints of dynamic callable anonymous mixins constructors. These mixin constructors are now marked callable by the dynamic interface annotator: https://dart-review.googlesource.com/c/sdk/+/430002 However, they are not directly invokeable and trying to compile the constructor entrypoints causes dart2wasm to crash. So we explicitly skip them when considering dynamic callable constructors. Note: This is blocking internal rolls as code patterns like this show up in our internal codebase. Change-Id: I76383aec07bc53a0dbd1581c0577cba370d956f9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/430801 Reviewed-by: Martin Kustermann Commit-Queue: Nate Biggs Auto-Submit: Nate Biggs --- pkg/dart2wasm/lib/dynamic_modules.dart | 4 +++- .../const_mixin_class/dynamic_interface.yaml | 7 +++++++ .../test/data/const_mixin_class/main.dart | 16 ++++++++++++++++ .../data/const_mixin_class/modules/entry1.dart | 8 ++++++++ .../data/const_mixin_class/shared/shared.dart | 9 +++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 pkg/dynamic_modules/test/data/const_mixin_class/dynamic_interface.yaml create mode 100644 pkg/dynamic_modules/test/data/const_mixin_class/main.dart create mode 100644 pkg/dynamic_modules/test/data/const_mixin_class/modules/entry1.dart create mode 100644 pkg/dynamic_modules/test/data/const_mixin_class/shared/shared.dart diff --git a/pkg/dart2wasm/lib/dynamic_modules.dart b/pkg/dart2wasm/lib/dynamic_modules.dart index b7001aab186..67ab4047be5 100644 --- a/pkg/dart2wasm/lib/dynamic_modules.dart +++ b/pkg/dart2wasm/lib/dynamic_modules.dart @@ -605,7 +605,9 @@ class DynamicModuleInfo { // These types do not have directly invokable constructors. translator.classInfo[member.enclosingClass]!.struct .isSubtypeOf(translator.objectInfo.struct)) { - passReference(member.reference); + if (!member.enclosingClass.isAnonymousMixin) { + passReference(member.reference); + } passReference(member.initializerReference); passReference(member.constructorBodyReference); } diff --git a/pkg/dynamic_modules/test/data/const_mixin_class/dynamic_interface.yaml b/pkg/dynamic_modules/test/data/const_mixin_class/dynamic_interface.yaml new file mode 100644 index 00000000000..43360b95cb7 --- /dev/null +++ b/pkg/dynamic_modules/test/data/const_mixin_class/dynamic_interface.yaml @@ -0,0 +1,7 @@ +# Copyright (c) 2025, 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: 'shared/shared.dart' + class: 'Foo' diff --git a/pkg/dynamic_modules/test/data/const_mixin_class/main.dart b/pkg/dynamic_modules/test/data/const_mixin_class/main.dart new file mode 100644 index 00000000000..391061726fe --- /dev/null +++ b/pkg/dynamic_modules/test/data/const_mixin_class/main.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2025, 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' show Foo; + +/// A dynamic module is allowed to extend a class in the dynamic interface and +/// override its members. +void main() async { + final o = (await helper.load('entry1.dart')); + Expect.equals(const Foo(), o); + helper.done(); +} diff --git a/pkg/dynamic_modules/test/data/const_mixin_class/modules/entry1.dart b/pkg/dynamic_modules/test/data/const_mixin_class/modules/entry1.dart new file mode 100644 index 00000000000..ec027e28121 --- /dev/null +++ b/pkg/dynamic_modules/test/data/const_mixin_class/modules/entry1.dart @@ -0,0 +1,8 @@ +// Copyright (c) 2025, 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'; + +@pragma('dyn-module:entry-point') +Object? dynamicModuleEntrypoint() => const Foo(); diff --git a/pkg/dynamic_modules/test/data/const_mixin_class/shared/shared.dart b/pkg/dynamic_modules/test/data/const_mixin_class/shared/shared.dart new file mode 100644 index 00000000000..c9402b403b0 --- /dev/null +++ b/pkg/dynamic_modules/test/data/const_mixin_class/shared/shared.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2025, 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. + +mixin Mixin {} + +class Foo with Mixin { + const Foo(); +}