-
Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathasync_main.swift
91 lines (76 loc) · 5.43 KB
/
async_main.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-sil -target %target-swift-5.1-abi-triple -parse-as-library %s | %FileCheck %s --check-prefix=CHECK-SIL
// RUN: %target-build-swift -target %target-swift-5.1-abi-triple -Xfrontend -parse-as-library %s -o %t_binary
// RUN: %target-codesign %t_binary
// RUN: %target-run %t_binary | %FileCheck %s --check-prefix=CHECK-EXEC
// REQUIRES: concurrency
// REQUIRES: executable_test
// REQUIRES: OS=macosx || OS=ios
// rdar://76038845
// REQUIRES: concurrency_runtime
// UNSUPPORTED: back_deployment_runtime
@MainActor
var foo: Int = 42
func asyncFunc() async {
print("Hello World!")
}
@main struct MyProgram {
static func main() async throws {
print("\(foo)")
foo += 1
await asyncFunc()
print("\(foo)")
}
}
// CHECK-EXEC: 42
// CHECK-EXEC-NEXT: Hello World!
// CHECK-EXEC-NEXT: 43
// static MyProgram.main()
// CHECK-SIL-LABEL: sil hidden @$s10async_main9MyProgramV0B0yyYaKFZ : $@convention(method) @async (@thin MyProgram.Type) -> @error any Error
// static MyProgram.$main()
// CHECK-SIL-LABEL: sil hidden @$s10async_main9MyProgramV5$mainyyYaKFZ : $@convention(method) @async (@thin MyProgram.Type) -> @error any Error
// async_Main
// CHECK-SIL-LABEL: sil private @async_Main : $@convention(thin) @async () -> () {
// call main
// CHECK-SIL: %0 = metatype $@thin MyProgram.Type // user: %2
// CHECK-SIL-NEXT: // function_ref static MyProgram.$main()
// CHECK-SIL-NEXT: %1 = function_ref @$s10async_main9MyProgramV5$mainyyYaKFZ : $@convention(method) @async (@thin MyProgram.Type) -> @error any Error // user: %2
// CHECK-SIL-NEXT: try_apply %1(%0) : $@convention(method) @async (@thin MyProgram.Type) -> @error any Error, normal bb1, error bb2 // id: %2
// unwrap error and exit or explode
// CHECK-SIL: bb1(%3 : $()):
// CHECK-SIL-NEXT: %4 = integer_literal $Builtin.Int32, 0
// CHECK-SIL-NEXT: %5 = struct $Int32 (%4 : $Builtin.Int32)
// CHECK-SIL-NEXT: // function_ref exit
// CHECK-SIL-NEXT: %6 = function_ref @exit : $@convention(c) (Int32) -> Never
// CHECK-SIL-NEXT: %7 = apply %6(%5) : $@convention(c) (Int32) -> Never
// CHECK-SIL-NEXT: unreachable
// CHECK-SIL: bb2(%9 : $any Error):
// CHECK-SIL-NEXT: %10 = builtin "errorInMain"(%9 : $any Error) : $()
// CHECK-SIL-NEXT: unreachable
// main
// CHECK-SIL-LABEL: sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
// CHECK-SIL: // function_ref async_Main
// CHECK-SIL-NEXT: [[ASYNC_MAIN_FN:%.*]] = function_ref @async_Main : $@convention(thin) @async () -> ()
// CHECK-SIL-NEXT: [[T0:%.*]] = integer_literal $Builtin.Int64, 2048
// CHECK-SIL-NEXT: [[FLAGS:%.*]] = struct $Int ([[T0]] : $Builtin.Int64)
// CHECK-SIL-NEXT: [[OPT_SERIAL_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-SIL-NEXT: [[GROUP:%.*]] = enum $Optional<Builtin.RawPointer>, #Optional.none
// CHECK-SIL-NEXT: [[TASK_EXECUTOR_UNOWNED:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-SIL-NEXT: [[TASK_EXECUTOR_OWNED:%.*]] = enum $Optional<any TaskExecutor>, #Optional.none
// CHECK-SIL-NEXT: [[TASK_NAME:%.*]] = enum $Optional<Builtin.RawPointer>, #Optional.none
// CHECK-SIL-NEXT: // function_ref thunk for @escaping @convention(thin) @async () -> ()
// CHECK-SIL-NEXT: [[THUNK_FN:%.*]] = function_ref @$sIetH_yts5Error_pIegHrzo_TR : $@convention(thin) @async (@convention(thin) @async () -> ()) -> (@out (), @error any Error)
// CHECK-SIL-NEXT: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]([[ASYNC_MAIN_FN]]) : $@convention(thin) @async (@convention(thin) @async () -> ()) -> (@out (), @error any Error)
// CHECK-SIL-NEXT: [[CONVERTED_THUNK:%.*]] = convert_function [[THUNK]] : $@async @callee_guaranteed () -> (@out (), @error any Error) to $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>
// CHECK-SIL-NEXT: [[TASK_RESULT:%.*]] = builtin "createAsyncTask"<()>([[FLAGS]] : $Int, [[OPT_SERIAL_EXECUTOR]] : $Optional<Builtin.Executor>, [[GROUP]] : $Optional<Builtin.RawPointer>, [[TASK_EXECUTOR_UNOWNED]] : $Optional<Builtin.Executor>, [[TASK_EXECUTOR_OWNED]] : $Optional<any TaskExecutor>, [[TASK_NAME]] : $Optional<Builtin.RawPointer>, [[CONVERTED_THUNK]] : $@async @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <()>) : $(Builtin.NativeObject, Builtin.RawPointer)
// CHECK-SIL-NEXT: [[TASK:%.*]] = tuple_extract [[TASK_RESULT]] : $(Builtin.NativeObject, Builtin.RawPointer), 0
// CHECK-SIL-NEXT: // function_ref swift_job_run
// CHECK-SIL-NEXT: [[RUN_FN:%.*]] = function_ref @swift_job_run : $@convention(thin) (UnownedJob, UnownedSerialExecutor) -> ()
// CHECK-SIL-NEXT: [[RAW_JOB:%.*]] = builtin "convertTaskToJob"([[TASK]] : $Builtin.NativeObject) : $Builtin.Job
// CHECK-SIL-NEXT: [[JOB:%.*]] = struct $UnownedJob ([[RAW_JOB]] : $Builtin.Job)
// CHECK-SIL-NEXT: [[RAW_MAIN_EXECUTOR:%.*]] = builtin "buildMainActorExecutorRef"() : $Builtin.Executor
// CHECK-SIL-NEXT: [[MAIN_EXECUTOR:%.*]] = struct $UnownedSerialExecutor ([[RAW_MAIN_EXECUTOR]] : $Builtin.Executor)
// CHECK-SIL-NEXT: apply [[RUN_FN]]([[JOB]], [[MAIN_EXECUTOR]]) : $@convention(thin) (UnownedJob, UnownedSerialExecutor) -> ()
// CHECK-SIL-NEXT: // function_ref swift_task_asyncMainDrainQueue
// CHECK-SIL-NEXT: [[DRAIN_FN:%.*]] = function_ref @swift_task_asyncMainDrainQueue : $@convention(thin) () -> Never
// CHECK-SIL-NEXT: apply [[DRAIN_FN]]() : $@convention(thin) () -> Never
// CHECK-SIL-NEXT: unreachable