Skip to content

Commit 0b92a72

Browse files
committed
Add runtime-async smoke tests for NativeAOT
1 parent eccb928 commit 0b92a72

5 files changed

Lines changed: 187 additions & 0 deletions

File tree

src/coreclr/jit/codegenloongarch64.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4404,6 +4404,14 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
44044404
genRecordAsyncResume(treeNode->AsVal());
44054405
break;
44064406

4407+
case GT_ASYNC_CONTINUATION:
4408+
genCodeForAsyncContinuation(treeNode);
4409+
break;
4410+
4411+
case GT_RETURN_SUSPEND:
4412+
genReturnSuspend(treeNode->AsUnOp());
4413+
break;
4414+
44074415
default:
44084416
{
44094417
#ifdef DEBUG

src/coreclr/jit/codegenriscv64.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4201,6 +4201,14 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
42014201
genCodeForSlliUw(treeNode->AsOp());
42024202
break;
42034203

4204+
case GT_ASYNC_CONTINUATION:
4205+
genCodeForAsyncContinuation(treeNode);
4206+
break;
4207+
4208+
case GT_RETURN_SUSPEND:
4209+
genReturnSuspend(treeNode->AsUnOp());
4210+
break;
4211+
42044212
default:
42054213
{
42064214
#ifdef DEBUG

src/tests/nativeaot/SmokeTests/UnitTests/Main.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
success &= RunTest(Devirtualization.Run);
1313
success &= RunTest(StackTraces.Run);
1414
success &= RunTest(Ordering.Run);
15+
success &= RunTest(RuntimeAsync.Run);
1516

1617
return success ? 100 : 1;
1718

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
using System.Threading.Tasks;
7+
8+
class RuntimeAsync
9+
{
10+
public const int Pass = 100;
11+
public const int Fail = -1;
12+
13+
internal static int Run()
14+
{
15+
if (TaskReturningAsyncTest.Run() != Pass)
16+
return Fail;
17+
18+
if (ValueTaskReturningAsyncTest.Run() != Pass)
19+
return Fail;
20+
21+
if (TaskWithResultTest.Run() != Pass)
22+
return Fail;
23+
24+
if (AwaitCompletedTaskTest.Run() != Pass)
25+
return Fail;
26+
27+
return Pass;
28+
}
29+
}
30+
31+
// Test basic Task-returning async method
32+
class TaskReturningAsyncTest
33+
{
34+
[RuntimeAsyncMethodGeneration(false)]
35+
static async Task SimpleAsyncMethod()
36+
{
37+
await Task.CompletedTask;
38+
}
39+
40+
public static int Run()
41+
{
42+
try
43+
{
44+
var task = SimpleAsyncMethod();
45+
task.Wait();
46+
Console.WriteLine("TaskReturningAsyncTest passed");
47+
return RuntimeAsync.Pass;
48+
}
49+
catch (Exception ex)
50+
{
51+
Console.WriteLine($"TaskReturningAsyncTest failed: {ex}");
52+
return RuntimeAsync.Fail;
53+
}
54+
}
55+
}
56+
57+
// Test ValueTask-returning async method
58+
class ValueTaskReturningAsyncTest
59+
{
60+
[RuntimeAsyncMethodGeneration(false)]
61+
static async ValueTask SimpleValueTaskAsync()
62+
{
63+
await Task.CompletedTask;
64+
}
65+
66+
public static int Run()
67+
{
68+
try
69+
{
70+
var task = SimpleValueTaskAsync();
71+
task.AsTask().Wait();
72+
Console.WriteLine("ValueTaskReturningAsyncTest passed");
73+
return RuntimeAsync.Pass;
74+
}
75+
catch (Exception ex)
76+
{
77+
Console.WriteLine($"ValueTaskReturningAsyncTest failed: {ex}");
78+
return RuntimeAsync.Fail;
79+
}
80+
}
81+
}
82+
83+
// Test Task<T> returning async method with result
84+
class TaskWithResultTest
85+
{
86+
[RuntimeAsyncMethodGeneration(false)]
87+
static async Task<int> ComputeAsync()
88+
{
89+
await Task.CompletedTask;
90+
return 42;
91+
}
92+
93+
public static int Run()
94+
{
95+
try
96+
{
97+
var task = ComputeAsync();
98+
int result = task.Result;
99+
if (result == 42)
100+
{
101+
Console.WriteLine("TaskWithResultTest passed");
102+
return RuntimeAsync.Pass;
103+
}
104+
else
105+
{
106+
Console.WriteLine($"TaskWithResultTest failed: expected 42, got {result}");
107+
return RuntimeAsync.Fail;
108+
}
109+
}
110+
catch (Exception ex)
111+
{
112+
Console.WriteLine($"TaskWithResultTest failed: {ex}");
113+
return RuntimeAsync.Fail;
114+
}
115+
}
116+
}
117+
118+
// Test awaiting a completed task (optimized fast path)
119+
class AwaitCompletedTaskTest
120+
{
121+
[RuntimeAsyncMethodGeneration(false)]
122+
static async Task<string> GetMessageAsync()
123+
{
124+
await Task.CompletedTask;
125+
return "Hello";
126+
}
127+
128+
[RuntimeAsyncMethodGeneration(false)]
129+
static async Task<string> CombineAsync()
130+
{
131+
string msg1 = await GetMessageAsync();
132+
string msg2 = await GetMessageAsync();
133+
return msg1 + " " + msg2;
134+
}
135+
136+
public static int Run()
137+
{
138+
try
139+
{
140+
var task = CombineAsync();
141+
string result = task.Result;
142+
if (result == "Hello Hello")
143+
{
144+
Console.WriteLine("AwaitCompletedTaskTest passed");
145+
return RuntimeAsync.Pass;
146+
}
147+
else
148+
{
149+
Console.WriteLine($"AwaitCompletedTaskTest failed: expected 'Hello Hello', got '{result}'");
150+
return RuntimeAsync.Fail;
151+
}
152+
}
153+
catch (Exception ex)
154+
{
155+
Console.WriteLine($"AwaitCompletedTaskTest failed: {ex}");
156+
return RuntimeAsync.Fail;
157+
}
158+
}
159+
}

src/tests/nativeaot/SmokeTests/UnitTests/UnitTests.csproj

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,27 @@
1212
<ReferenceXUnitWrapperGenerator>false</ReferenceXUnitWrapperGenerator>
1313

1414
<IlcOrderFile>order.txt</IlcOrderFile>
15+
16+
<!-- Enable runtime-async preview feature -->
17+
<EnablePreviewFeatures>true</EnablePreviewFeatures>
18+
<Features>$(Features);runtime-async=on</Features>
1519
</PropertyGroup>
20+
21+
<ItemGroup>
22+
<CLRTestEnvironmentVariable Include="DOTNET_RuntimeAsync" Value="1" />
23+
</ItemGroup>
24+
1625
<ItemGroup>
1726
<Compile Include="BasicThreading.cs" />
1827
<Compile Include="Delegates.cs" />
1928
<Compile Include="Devirtualization.cs" />
2029
<Compile Include="Generics.cs" />
2130
<Compile Include="Interfaces.cs" />
2231
<Compile Include="Ordering.cs" />
32+
<Compile Include="RuntimeAsync.cs" />
2333
<Compile Include="Threading.cs" />
2434
<Compile Include="StackTraces.cs" />
2535
<Compile Include="Main.cs" />
36+
<Compile Include="..\..\..\async\RuntimeAsyncMethodGenerationAttribute.cs" Link="RuntimeAsyncMethodGenerationAttribute.cs" />
2637
</ItemGroup>
2738
</Project>

0 commit comments

Comments
 (0)