Skip to content

Commit 23cf6a1

Browse files
committed
[Sema] RuntimeMetadata: Add support for async functions and actor methods
Add support for global async functions and actor-isolated methods by determining isolation context of the method attribute is associated with and injecting try/await when appropriate.
1 parent 699ef07 commit 23cf6a1

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

lib/Sema/TypeCheckRuntimeMetadataAttr.cpp

+34-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
#include "TypeCheckConcurrency.h"
1718
#include "TypeChecker.h"
1819
#include "swift/AST/ASTContext.h"
1920
#include "swift/AST/ASTMangler.h"
21+
#include "swift/AST/ActorIsolation.h"
2022
#include "swift/AST/Attr.h"
2123
#include "swift/AST/Decl.h"
2224
#include "swift/AST/Initializer.h"
@@ -170,9 +172,39 @@ static ClosureExpr *synthesizeMethodThunk(DeclContext *thunkDC,
170172
}
171173
}
172174

173-
auto *call = CallExpr::createImplicit(
175+
Expr *call = CallExpr::createImplicit(
174176
ctx, memberRef, ArgumentList::createImplicit(ctx, arguments));
175177

178+
bool isAsync = false;
179+
bool isThrows = method->hasThrows();
180+
181+
switch (getActorIsolation(method)) {
182+
case ActorIsolation::Unspecified:
183+
case ActorIsolation::Independent: {
184+
isAsync = method->hasAsync();
185+
break;
186+
}
187+
188+
case ActorIsolation::ActorInstance: {
189+
isAsync = true;
190+
isThrows |= nominal->isDistributedActor();
191+
break;
192+
}
193+
194+
case ActorIsolation::GlobalActor:
195+
isAsync = true;
196+
LLVM_FALLTHROUGH;
197+
case ActorIsolation::GlobalActorUnsafe: {
198+
break;
199+
}
200+
}
201+
202+
if (isAsync)
203+
call = AwaitExpr::createImplicit(ctx, /*awaitLoc=*/SourceLoc(), call);
204+
205+
if (isThrows)
206+
call = TryExpr::createImplicit(ctx, /*tryLoc=*/SourceLoc(), call);
207+
176208
body.push_back(new (ctx) ReturnStmt(/*ReturnLoc=*/SourceLoc(), call,
177209
/*implicit=*/true));
178210
}
@@ -282,6 +314,7 @@ Expr *SynthesizeRuntimeMetadataAttrGenerator::evaluate(
282314
return nullptr;
283315

284316
TypeChecker::contextualizeInitializer(initContext, result);
317+
checkInitializerActorIsolation(initContext, result);
285318
TypeChecker::checkInitializerEffects(initContext, result);
286319

287320
return result;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module-path=%t/RAD.swiftmodule -module-name=RAD -enable-experimental-feature RuntimeDiscoverableAttrs -disable-availability-checking %S/Inputs/runtime_attrs.swift
3+
// RUN: %target-swift-frontend -primary-file %s -emit-ir -I %t -swift-version 5 -enable-experimental-feature RuntimeDiscoverableAttrs -disable-availability-checking | %IRGenFileCheck %s
4+
5+
// REQUIRES: asserts
6+
// REQUIRES: OS=macosx
7+
// REQUIRES: concurrency
8+
9+
// CHECK: @"$s28runtime_attributes_on_actors9TestActorC15asyncExternallyyyKcvpfaAA17FlagForAsyncFuncsHF"
10+
// CHECK: @"$s28runtime_attributes_on_actors9TestActorC11doSomethingyyYaKcvpfaAA17FlagForAsyncFuncsHF"
11+
// CHECK: @"$s28runtime_attributes_on_actors9TestActorC11doSomethingyySiYacvpfaAA17FlagForAsyncFuncsHF"
12+
// CHECK: @"$s28runtime_attributes_on_actors9TestActorC11doSomething_1xySi_SaySiGztYacvpfaAA17FlagForAsyncFuncsHF"
13+
// CHECK: @"$s28runtime_attributes_on_actors13globalAsyncFnSaySSGyYacvpfaAA07FlagForF5FuncsHF"
14+
15+
// CHECK: @"$s28runtime_attributes_on_actors17FlagForAsyncFuncsVHa" = internal constant
16+
// CHECK-SAME: i32 5
17+
// CHECK-SAME: %swift.accessible_function* @"$s28runtime_attributes_on_actors9TestActorC15asyncExternallyyyKcvpfaAA17FlagForAsyncFuncsHF"
18+
// CHECK-SAME: %swift.accessible_function* @"$s28runtime_attributes_on_actors9TestActorC11doSomethingyyYaKcvpfaAA17FlagForAsyncFuncsHF"
19+
// CHECK-SAME: %swift.accessible_function* @"$s28runtime_attributes_on_actors9TestActorC11doSomethingyySiYacvpfaAA17FlagForAsyncFuncsHF"
20+
// CHECK-SAME: %swift.accessible_function* @"$s28runtime_attributes_on_actors9TestActorC11doSomething_1xySi_SaySiGztYacvpfaAA17FlagForAsyncFuncsHF"
21+
// CHECK-SAME: %swift.accessible_function* @"$s28runtime_attributes_on_actors13globalAsyncFnSaySSGyYacvpfaAA07FlagForF5FuncsHF"
22+
23+
@runtimeMetadata
24+
struct FlagForAsyncFuncs {
25+
init<Act>(attachedTo: (Act) async throws -> Void) {}
26+
init<Act>(attachedTo: (Act, Int, inout [Int]) async throws -> Void) {}
27+
init<Act>(attachedTo: (Act, Int) async -> Void) {}
28+
init(attachedTo: () async -> [String]) {}
29+
}
30+
31+
actor TestActor {
32+
// CHECK-LABEL: define hidden swiftcc void @"$s28runtime_attributes_on_actors9TestActorC15asyncExternallyyyKcvpfaAA17FlagForAsyncFuncs"(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg* noalias nocapture sret(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg) %0)
33+
@FlagForAsyncFuncs func asyncExternally() throws {
34+
}
35+
36+
// CHECK-LABEL: define hidden swiftcc void @"$s28runtime_attributes_on_actors9TestActorC11doSomethingyyYaKcvpfaAA17FlagForAsyncFuncs"(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg* noalias nocapture sret(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg) %0)
37+
@FlagForAsyncFuncs func doSomething() async throws {
38+
}
39+
40+
// CHECK-LABEL: define hidden swiftcc void @"$s28runtime_attributes_on_actors9TestActorC11doSomethingyySiYacvpfaAA17FlagForAsyncFuncs"(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg* noalias nocapture sret(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg) %0)
41+
@FlagForAsyncFuncs nonisolated func doSomething(_: Int) async {
42+
}
43+
44+
// CHECK-LABEL: define hidden swiftcc void @"$s28runtime_attributes_on_actors9TestActorC11doSomething_1xySi_SaySiGztYacvpfaAA17FlagForAsyncFuncs"(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg* noalias nocapture sret(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg) %0)
45+
@FlagForAsyncFuncs func doSomething(_: Int, x: inout [Int]) async {
46+
}
47+
}
48+
49+
// CHECK-LABEL: define hidden swiftcc void @"$s28runtime_attributes_on_actors13globalAsyncFnSaySSGyYacvpfaAA07FlagForF5Funcs"(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg* noalias nocapture sret(%T28runtime_attributes_on_actors17FlagForAsyncFuncsVSg) %0)
50+
@FlagForAsyncFuncs
51+
func globalAsyncFn() async -> [String] {
52+
return []
53+
}

test/type/runtime_discoverable_attrs.swift

+27
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,30 @@ struct TestMutatingMethods {
185185
(q: "", a: 42)
186186
}
187187
}
188+
189+
@runtimeMetadata
190+
struct FlagForAsyncFuncs {
191+
init<Act>(attachedTo: (Act) async throws -> Void) {}
192+
init<Act>(attachedTo: (Act, Int, inout [Int]) async throws -> Void) {}
193+
init<Act>(attachedTo: (Act, Int) async -> Void) {}
194+
init(attachedTo: () async -> [String]) {}
195+
}
196+
197+
actor TestActor {
198+
@FlagForAsyncFuncs func asyncExternally() throws {
199+
}
200+
201+
@FlagForAsyncFuncs func doSomething() async throws {
202+
}
203+
204+
@FlagForAsyncFuncs nonisolated func doSomething(_: Int) async {
205+
}
206+
207+
@FlagForAsyncFuncs func doSomething(_: Int, x: inout [Int]) async {
208+
}
209+
}
210+
211+
@FlagForAsyncFuncs
212+
func globalAsyncFn() async -> [String] {
213+
return []
214+
}

0 commit comments

Comments
 (0)