$ the-wire · showcase
WebAssembly runtime fixes narrow long-local reads; F# strips dead feature flags
By RepoJournal · Filed · About .NET
A wasm codegen bug that could read the wrong half of a long local is fixed, while F# removes three always-on feature flags and .NET 12 branding begins.
The wasm backend in dotnet/runtime fixes a bug where Morph folds `CAST(int <- long, LCL_VAR long)` into `LCL_VAR int` naming the same long local; codegen paths that re-materialize a multi-use operand failed to emit the `i32.wrap_i64`, so narrowing reads could return the wrong half of a 64-bit value [1]. Separate wasm work routes framework R2R through the SDK's normal pipeline for browser CoreCLR, removing a duplicated hand-built `Exec` path [2], and replaces the hardcoded 7-entry struct-size table in the CoreCLR P/Invoke generator with crossgen2's real field-layout engine, eliminating the WASM0067 hard build error for unknown multi-field structs [3]. PemEncoding.TryFind also gets faster on degenerate inputs by checking the next hyphen for PostEB before running IsValidBase64 checks [4].
F# removes three language feature flags that have been always-on since their minimum selectable `--langversion`: `ArithmeticInLiterals` (since F# 8.0), `OverloadsForCustomOperations` (since F# 6.0), and `ExtendedFixedBindings` (since F# 8.0) [5][6][7]. Each flag's guards collapse to the enabled path, and the `--disableLanguageFeature:` commands for them are now unrecognized, which is a breaking change only for tooling that still passed those switches.
In dotnet/android, typemap work continues with an allocation-free Java-to-managed proxy lookup path and a `ref` builder replacing iterator-based proxy collection [8]. The AndroidSystem native path statics move from `std::string`/`std::array<std::string, 1>` with dynamic initialization to a POD buffer, dropping per-member guard variables and `atexit` registrations from every consuming binary [9]. Meanwhile, dotnet/dotnet initializes .NET 12 branding to alpha.1 [10], moving the only known flag up to effect.
Action items
- → Update to a runtime build containing the wasm long-local narrowing fix before shipping browser workloads that divide two long locals dotnet/runtime [plan]
- → If you pass --disableLanguageFeature:ArithmeticInLiterals, OverloadsForCustomOperations, or ExtendedFixedBindings, remove those switches from your F# build dotnet/fsharp [immediate]
- → Watch for the .NET 12 branding and channel mapping to land in dotnet/performance (dotnet12 and dotnet12-transport feeds) dotnet/dotnet [monitor]
References
- [1] [wasm] Narrow multi-use operands read out of long locals (#133210) ↗ dotnet/runtime
- [2] Use SDK pipeline for WebAssembly framework R2R ↗ dotnet/runtime
- [3] [wasm] Compute CoreCLR P/Invoke struct sizes with crossgen2's type system ↗ dotnet/runtime
- [4] Improve PemEncoding.TryFind perf with degenerate inputs ↗ dotnet/runtime
- [5] Remove the ArithmeticInLiterals language feature flag ↗ dotnet/fsharp
- [6] Remove always-on language feature flag OverloadsForCustomOperations ↗ dotnet/fsharp
- [7] Remove always-on ExtendedFixedBindings language feature flag (#20429) ↗ dotnet/fsharp
- [8] [typemap] Reduce Java-to-managed proxy lookup allocations ↗ dotnet/android
- [9] [native] Replace the AndroidSystem path statics with a POD buffer (#12552) ↗ dotnet/android
- [10] [main] Initialize .NET 12 branding ↗ dotnet/dotnet