Skip to content

Commit 37db1af

Browse files
Merge pull request #80135 from nate-chandler/general-coro/20250319/1
[CoroutineAccessors] Store CFPs in descriptors.
2 parents a8111e4 + a4bf94d commit 37db1af

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

Diff for: include/swift/ABI/Metadata.h

+9
Original file line numberDiff line numberDiff line change
@@ -582,13 +582,16 @@ struct TargetMethodDescriptor {
582582
union {
583583
TargetCompactFunctionPointer<Runtime, void> Impl;
584584
TargetRelativeDirectPointer<Runtime, void> AsyncImpl;
585+
TargetRelativeDirectPointer<Runtime, void> CoroImpl;
585586
};
586587

587588
// TODO: add method types or anything else needed for reflection.
588589

589590
void *getImpl() const {
590591
if (Flags.isAsync()) {
591592
return AsyncImpl.get();
593+
} else if (Flags.isCalleeAllocatedCoroutine()) {
594+
return CoroImpl.get();
592595
} else {
593596
return Impl.get();
594597
}
@@ -665,13 +668,16 @@ struct TargetMethodOverrideDescriptor {
665668
union {
666669
TargetCompactFunctionPointer<Runtime, void, /*nullable*/ true> Impl;
667670
TargetRelativeDirectPointer<Runtime, void, /*nullable*/ true> AsyncImpl;
671+
TargetRelativeDirectPointer<Runtime, void, /*nullable*/ true> CoroImpl;
668672
};
669673

670674
void *getImpl() const {
671675
auto *baseMethod = Method.get();
672676
assert(baseMethod && "no base method");
673677
if (baseMethod->Flags.isAsync()) {
674678
return AsyncImpl.get();
679+
} else if (baseMethod->Flags.isCalleeAllocatedCoroutine()) {
680+
return CoroImpl.get();
675681
} else {
676682
return Impl.get();
677683
}
@@ -5170,6 +5176,7 @@ class DynamicReplacementDescriptor {
51705176
union {
51715177
TargetCompactFunctionPointer<InProcess, void, false> replacementFunction;
51725178
TargetRelativeDirectPointer<InProcess, void, false> replacementAsyncFunction;
5179+
TargetRelativeDirectPointer<InProcess, void, false> replacementCoroFunction;
51735180
};
51745181
RelativeDirectPointer<DynamicReplacementChainEntry, false> chainEntry;
51755182
uint32_t flags;
@@ -5179,6 +5186,8 @@ class DynamicReplacementDescriptor {
51795186
void *getReplacementFunction() const {
51805187
if (replacedFunctionKey->isAsync()) {
51815188
return replacementAsyncFunction.get();
5189+
} else if (replacedFunctionKey->isCalleeAllocatedCoroutine()) {
5190+
return replacementCoroFunction.get();
51825191
} else {
51835192
return replacementFunction.get();
51845193
}

Diff for: test/IRGen/run-coroutine_accessors.swift

+79
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@
6060
public protocol ResilientWrapping {
6161
associatedtype Wrapped
6262
var wrapped: Wrapped { read set }
63+
var wrapped2: Wrapped { read set }
64+
}
65+
extension ResilientWrapping {
66+
public var wrapped2: Wrapped {
67+
read {
68+
yield wrapped
69+
}
70+
modify {
71+
yield &wrapped
72+
}
73+
}
6374
}
6475

6576
public struct ResilientBoxtional<T> : ResilientWrapping {
@@ -80,6 +91,7 @@ public struct ResilientBoxtional<T> : ResilientWrapping {
8091
}
8192

8293
open class ResilientWrappingClass<Wrapped> {
94+
public init() {}
8395
open var wrapped: Wrapped {
8496
read {
8597
fatalError()
@@ -162,6 +174,39 @@ struct MaybePtrBox<T> {
162174
}
163175
}
164176

177+
struct Boxtional<T> : ResilientWrapping {
178+
var storage: T?
179+
init(_ t: T?) {
180+
self.storage = t
181+
}
182+
typealias Wrapped = T?
183+
184+
var wrapped : T? {
185+
read {
186+
yield storage
187+
}
188+
modify {
189+
yield &storage
190+
}
191+
}
192+
}
193+
194+
class NonresilientResilientWrappingSubclass<X : ResilientWrapping> : ResilientWrappingClass<X.Wrapped> {
195+
init(_ impl: X) {
196+
self.impl = impl
197+
super.init()
198+
}
199+
var impl: X
200+
override var wrapped: X.Wrapped {
201+
read {
202+
yield impl.wrapped
203+
}
204+
modify {
205+
yield &impl.wrapped
206+
}
207+
}
208+
}
209+
165210
protocol AsyncMutatable {
166211
mutating func mutate() async
167212
}
@@ -333,6 +378,24 @@ struct M {
333378
// CHECK: "hihi"
334379
print(v2.wrapped)
335380
}
381+
static func mutateResilientWrapped2<T : ResilientWrapping>(_ t: inout T) where T.Wrapped : Mutatable {
382+
t.wrapped2.mutate()
383+
}
384+
static func resilient_proto_default_main() {
385+
var v1 = Boxtional(Optional<Stringgg>.none)
386+
// CHECK: nil
387+
print(v1.wrapped)
388+
mutateResilientWrapped(&v1)
389+
// CHECK: nil
390+
print(v1.wrapped)
391+
392+
var v2 = Boxtional(Stringgg(value: "hi"))
393+
// CHECK: "hi"
394+
print(v2.wrapped)
395+
mutateResilientWrapped(&v2)
396+
// CHECK: "hihi"
397+
print(v2.wrapped)
398+
}
336399
static func mutateWrappedInResilientClass<T : Mutatable>(_ t: ResilientWrappingClass<T>) {
337400
t.wrapped.mutate()
338401
}
@@ -350,12 +413,28 @@ struct M {
350413
// CHECK: "hihi"
351414
print(v2.wrapped)
352415
}
416+
static func resilient_subclass_main() {
417+
let v1 = MaybePtrBox(Optional<Stringgg>.none)
418+
// CHECK: nil
419+
print(v1.wrapped)
420+
mutateWrappedInResilientClass(NonresilientResilientWrappingSubclass(v1))
421+
// CHECK: nil
422+
print(v1.wrapped)
423+
let v2 = MaybePtrBox(Stringgg(value: "hi"))
424+
// CHECK: "hi"
425+
print(v2.wrapped)
426+
mutateWrappedInResilientClass(NonresilientResilientWrappingSubclass(v2))
427+
// CHECK: "hihi"
428+
print(v2.wrapped)
429+
}
353430
static func main() async {
354431
sync_main()
355432
await async_main()
356433
proto_main()
357434
class_main()
358435
resilient_proto_main()
436+
resilient_proto_default_main()
359437
resilient_class_main()
438+
resilient_subclass_main()
360439
}
361440
}

0 commit comments

Comments
 (0)