diff --git a/sdk/lib/_internal/wasm/lib/named_parameters.dart b/sdk/lib/_internal/wasm/lib/named_parameters.dart index 59365736447..0608deb82d1 100644 --- a/sdk/lib/_internal/wasm/lib/named_parameters.dart +++ b/sdk/lib/_internal/wasm/lib/named_parameters.dart @@ -5,15 +5,24 @@ part of "core_patch.dart"; /// Finds a named parameter in a named parameter list passed to a dynamic -/// forwarder and returns the index of the value of that named parameter. -/// Returns `null` if the name is not in the list. +/// forwarder or `Function.apply` and returns the index of the value of that +/// named parameter. Returns `null` if the name is not in the list. @pragma("wasm:entry-point") int? _getNamedParameterIndex( WasmArray namedArguments, Symbol paramName, ) { for (int i = 0; i < namedArguments.length; i += 2) { - if (identical(namedArguments[i], paramName)) { + // `Symbol.==` does not check identity so we have a fast path here checking + // identities. + // + // We can't check just identities as the symbols in the list may not be + // constants in `Function.apply`. + // + // Also, `paramName` will always be a constant, so with `--minify` it can + // only be equal to a symbol in the list if it's also identical to it. + if (identical(namedArguments[i], paramName) || + (!minify && unsafeCast(namedArguments[i]) == paramName)) { return i + 1; } } diff --git a/tests/web/wasm/function_apply_minify_test.dart b/tests/web/wasm/function_apply_minify_test.dart new file mode 100644 index 00000000000..8adfb98a5d5 --- /dev/null +++ b/tests/web/wasm/function_apply_minify_test.dart @@ -0,0 +1,25 @@ +// 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. + +// dart2wasmOptions=--extra-compiler-option=--minify + +import 'package:expect/expect.dart'; + +void f({int a = 0}) { + Expect.equals(123, a); +} + +bool get runtimeTrue => int.parse('1') == 1; + +void main() { + // With minification, non-const symbols won't be identical or equal to the + // const symbols, so `Symbol('a')` here won't match `a` in the `f`'s named + // parameters and `Function.apply` will throw an error. + Expect.throws( + () => Function.apply((runtimeTrue ? f : (() {})), [], {Symbol('a'): 123}), + ); + + // `const` symbols will work as before. + Function.apply((runtimeTrue ? f : (() {})), [], {#a: 123}); +}