[mono][AOT] gsharedvt method calling INumberBase<T>.TryParse fails in aot-only mode
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 38/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- csharp
調査の方向性
Start by tracing Mono full AOT generic sharing for the constrained INumber<T>.TryParse call in BareHolder<T>.Set; the report points to mini-generic-sharing.c and mini_instantiate_gshared_info. Reproduce with the provided iOS AOT setup, comparing the reflection-created closed type with direct construction and interpreter mode. Done when the generic value type parses successfully in AOT-only mode without JIT compilation.
索引モデルが issue の本文から書いたものです。
説明
Description
With Mono full AOT on iOS (UseInterpreter=false), a method on a generic type over a value type that calls T.TryParse(string, NumberStyles, IFormatProvider, out T) fails if the AOT compiler never saw the closed type and it has to run as gsharedvt code. The same method works when the closed type is constructed directly, and with the interpreter.
This came from MudBlazor's slider crashing MAUI Blazor Hybrid apps on iPhone (https://github.com/MudBlazor/MudBlazor/issues/14134). Blazor creates components from a Type and names MudSlider<int> only as a type argument, so the slider always runs as gsharedvt code.
Reproduction Steps
A class library (built with Optimize=true):
using System.Globalization;
using System.Numerics;
public abstract class BareBase
{
public abstract bool Set(string text);
public abstract string Text { get; }
}
public sealed class BareHolder<T> : BareBase where T : struct, INumber<T>
{
private T _value;
public override string Text => _value.ToString(null, CultureInfo.InvariantCulture);
public override bool Set(string text)
{
if (!T.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
{
return false;
}
_value = result;
return true;
}
}
public static class BareFactory
{
public static BareBase Create<THolder>() where THolder : BareBase => (BareBase)Activator.CreateInstance(typeof(THolder))!;
}
Called from an iOS app (net10.0-ios, UseInterpreter=false, MtouchLink=SdkOnly):
BareFactory.Create<BareHolder<long>>().Set("181"); // throws
new BareHolder<short>().Set("181"); // works
Expected behavior
Set parses the value, as it does with the interpreter or when the closed type is constructed directly.
Actual behavior
System.ExecutionEngineException: Attempting to JIT compile method 'bool Issue14134.BareHolder`1<long>:Set (string)' while running in aot-only mode.
When the call is inside an async method, the runtime aborts instead:
* Assertion at src/mono/mono/mini/mini-generic-sharing.c:2761, condition `is_ok (error)' not met, function:mini_instantiate_gshared_info, Attempting to JIT compile method 'void Issue14134.SvmAsyncHolder`1/<SetValueTextAsync>d__5<long>:MoveNext ()' while running in aot-only mode.
The reporter's physical iPhone build asserted iface_offset != -1 in mini-generic-sharing.c instead.
Regression?
Unknown.
Known Workarounds
- Construct the closed type where the AOT compiler sees it, for example
new BareHolder<long>()in a method that never runs. - Avoid
T.TryParse:double.TryParseordecimal.TryParsefollowed byT.CreateSaturatingworks in the same gsharedvt context, as doT.Zero,T.OneandT.CreateTruncating. MudBlazor does this in https://github.com/MudBlazor/MudBlazor/pull/14136.
Moving T.TryParse into a separate generic method doesn't help. The gsharedvt caller resolves that method on entry and Mono tries to JIT it, even when the call isn't reached.
Configuration
.NET SDK 10.0.403, runtime 10.0.14 (10.0.13 too), iOS workload 27.1.10018, Xcode 27.1, iOS 27.1 arm64 simulator, Debug and Release.
Other information
Possibly related: https://github.com/dotnet/runtime/issues/118697
- 主要言語
- C#
- スター
- 18.4k
- フォーク
- 5.8k
- 平均マージ
- 2日 12時間
- マージ済み PR(30日)
- 581
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
dotnet/runtime のほかの issue
-
area-System.Collections untriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
dotnet/runtime#137167 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Incorrect loop bound in SizeOptIListSelectIterator.ToList対応中かも @equmagg が 2 日前に担当しました。 オープンarea-System.Collections untriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
dotnet/runtime#137126 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
DbTransaction.SupportsSavepoints docs say Release/ReleaseAsync are expected to throw, but they are no-ops by design対応中かも @alaricd が 3 日前に担当しました。 オープンarea-System.Transactions untriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
dotnet/runtime#137040 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
FileSystemGlobbing: Matcher throws ArgumentOutOfRangeException when the rootDir is the same value as the file対応中かも @makazeu が 4 日前に担当しました。 オープンarea-Extensions-FileSystem
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
dotnet/runtime#136989 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Configuration binder source generator emits unqualified List<T> when binding arrays without implicit usings対応中かも @makazeu が 4 日前に担当しました。 オープンarea-Extensions-Configuration bug source-generator
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
dotnet/runtime#136972 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
似ている issue
-
Assert.That on a null non-generic IEnumerable throws ArgumentNullException, so IsNull() cannot passオープンbug P2
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
area/automation area/sdk kind/bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
unoplatform/uno.templates#2406 ·
メンテナーはふだん 1 日以内に返信
-
bug frontend ui
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
agentic-workflows
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
documentation trivial
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信