Skip to content

Commit 89009fa

Browse files
authored
Merge pull request #72622 from kubamracek/cp-6.0-embedded-add-ivar-destroyers
[6.0 cherry-pick] [embedded] Add IVarDestroyers into class metadata, add support for throws in initializers
2 parents fc7389f + 3e63085 commit 89009fa

File tree

9 files changed

+142
-10
lines changed

9 files changed

+142
-10
lines changed

lib/IRGen/ClassMetadataVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ template <class Impl> class ClassMetadataVisitor
7676
asImpl().noteAddressPoint();
7777
asImpl().addEmbeddedSuperclass(classTy);
7878
asImpl().addDestructorFunction();
79+
asImpl().addIVarDestroyer();
7980
addEmbeddedClassMembers(Target);
8081
}
8182

@@ -87,6 +88,7 @@ template <class Impl> class ClassMetadataVisitor
8788
asImpl().noteAddressPoint();
8889
asImpl().addSuperclass();
8990
asImpl().addDestructorFunction();
91+
asImpl().addIVarDestroyer();
9092
addEmbeddedClassMembers(Target);
9193
return;
9294
}

lib/IRGen/GenMeta.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4028,6 +4028,23 @@ namespace {
40284028
}
40294029

40304030
void addIVarDestroyer() {
4031+
if (IGM.Context.LangOpts.hasFeature(Feature::Embedded)) {
4032+
llvm::Constant *ptr = nullptr;
4033+
for (const SILVTable::Entry &entry : VTable->getEntries()) {
4034+
if (entry.getMethod().kind == SILDeclRef::Kind::IVarDestroyer) {
4035+
ptr = IGM.getAddrOfSILFunction(entry.getImplementation(), NotForDefinition);
4036+
break;
4037+
}
4038+
}
4039+
if (ptr) {
4040+
B.addSignedPointer(ptr, IGM.getOptions().PointerAuth.HeapDestructors,
4041+
PointerAuthEntity::Special::HeapDestructor);
4042+
} else {
4043+
B.addNullPointer(IGM.FunctionPtrTy);
4044+
}
4045+
return;
4046+
}
4047+
40314048
if (asImpl().getFieldLayout().hasObjCImplementation())
40324049
return;
40334050

stdlib/public/SwiftShims/swift/shims/EmbeddedShims.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,22 @@ _swift_embedded_invoke_heap_object_destroy(void *object) {
6262
#endif
6363
}
6464

65+
static inline void
66+
_swift_embedded_invoke_heap_object_optional_ivardestroyer(void *object, void *metadata) {
67+
void **ivardestroyer_location = &((void **)metadata)[2];
68+
if (*ivardestroyer_location) {
69+
#if __has_feature(ptrauth_calls)
70+
(*(HeapObjectDestroyer __ptrauth(0, 1, 0xbbbf) *)ivardestroyer_location)(object);
71+
#else
72+
(*(HeapObjectDestroyer *)ivardestroyer_location)(object);
73+
#endif
74+
}
75+
}
76+
77+
static inline void *_swift_embedded_get_heap_object_metadata_pointer(void *object) {
78+
return ((EmbeddedHeapObject *)object)->metadata;
79+
}
80+
6581
static inline void _swift_embedded_set_heap_object_metadata_pointer(void *object, void *metadata) {
6682
((EmbeddedHeapObject *)object)->metadata = metadata;
6783
}

stdlib/public/core/EmbeddedRuntime.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ import SwiftShims
1717
public struct ClassMetadata {
1818
var superclassMetadata: UnsafeMutablePointer<ClassMetadata>?
1919

20-
// There is no way to express the actual calling convention on the heap desroy
20+
// There is no way to express the actual calling convention on this
2121
// function (swiftcc with 'self') currently, so let's use UnsafeRawPointer
2222
// and a helper function in C (_swift_embedded_invoke_heap_object_destroy).
2323
var destroy: UnsafeRawPointer
24+
25+
// There is no way to express the actual calling convention on this
26+
// function (swiftcc with 'self') currently, so let's use UnsafeRawPointer
27+
// and a helper function in C (_swift_embedded_invoke_heap_object_optional_ivardestroyer).
28+
var ivarDestroyer: UnsafeRawPointer?
2429
}
2530

2631
public struct HeapObject {
@@ -116,6 +121,20 @@ func swift_deallocClassInstance(object: UnsafeMutablePointer<HeapObject>, alloca
116121
free(object._rawValue)
117122
}
118123

124+
@_cdecl("swift_deallocPartialClassInstance")
125+
public func swift_deallocPartialClassInstance(object: Builtin.RawPointer, metadata: Builtin.RawPointer, allocatedSize: Int, allocatedAlignMask: Int) {
126+
swift_deallocPartialClassInstance(object: UnsafeMutablePointer<HeapObject>(object), metadata: UnsafeMutablePointer<ClassMetadata>(metadata), allocatedSize: allocatedSize, allocatedAlignMask: allocatedAlignMask)
127+
}
128+
129+
func swift_deallocPartialClassInstance(object: UnsafeMutablePointer<HeapObject>, metadata: UnsafeMutablePointer<ClassMetadata>, allocatedSize: Int, allocatedAlignMask: Int) {
130+
var classMetadata = _swift_embedded_get_heap_object_metadata_pointer(object).assumingMemoryBound(to: ClassMetadata.self)
131+
while classMetadata != metadata {
132+
_swift_embedded_invoke_heap_object_optional_ivardestroyer(object, classMetadata)
133+
guard let superclassMetadata = classMetadata.pointee.superclassMetadata else { break }
134+
classMetadata = superclassMetadata
135+
}
136+
}
137+
119138
@_cdecl("swift_initStaticObject")
120139
public func swift_initStaticObject(metadata: Builtin.RawPointer, object: Builtin.RawPointer) -> Builtin.RawPointer {
121140
return swift_initStaticObject(metadata: UnsafeMutablePointer<ClassMetadata>(metadata), object: UnsafeMutablePointer<HeapObject>(object))._rawValue

test/embedded/classes-generic-no-stdlib.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ public func bar(t: T2) -> MyClass<T2> {
5050
// CHECK-SIL: }
5151

5252

53-
// CHECK-IR: @"$s4main7MyClassCyAA2T2VGN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfDAA2T2V_Tg5", ptr @"$s4main7MyClassC1txvgAA2T2V_Tg5", ptr @"$s4main7MyClassC1txvsAA2T2V_Tg5", ptr @"$s4main7MyClassC1txvMAA2T2V_Tg5", ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tg5" }>
54-
// CHECK-IR: @"$s4main7MyClassCyAA2T1VGN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfDAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvgAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvsAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvMAA2T1V_Tg5", ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tg5" }>
53+
// CHECK-IR: @"$s4main7MyClassCyAA2T2VGN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfDAA2T2V_Tg5", ptr null, ptr @"$s4main7MyClassC1txvgAA2T2V_Tg5", ptr @"$s4main7MyClassC1txvsAA2T2V_Tg5", ptr @"$s4main7MyClassC1txvMAA2T2V_Tg5", ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T2V_Tg5" }>
54+
// CHECK-IR: @"$s4main7MyClassCyAA2T1VGN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfDAA2T1V_Tg5", ptr null, ptr @"$s4main7MyClassC1txvgAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvsAA2T1V_Tg5", ptr @"$s4main7MyClassC1txvMAA2T1V_Tg5", ptr @"$s4main7MyClassC1tACyxGx_tcfCAA2T1V_Tg5" }>
5555

5656
// CHECK-IR-DAG: define {{.*}}void @"$s4main7MyClassC1txvgAA2T1V_Tg5"(ptr swiftself %0)
5757
// CHECK-IR-DAG: define {{.*}}i1 @"$s4main7MyClassC1txvgAA2T2V_Tg5"(ptr swiftself %0)

test/embedded/classes-methods-no-stdlib.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ public class MySubClass: MyClass {
1111
override func foo() { }
1212
}
1313

14-
// CHECK: @"$s4main7MyClassCN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfD", ptr @"$s4main7MyClassC3fooyyF", ptr @"$s4main7MyClassC3baryyF", ptr @swift_deletedMethodError }>
15-
// CHECK: @"$s4main10MySubClassCN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr }> <{ ptr @"$s4main7MyClassCN", ptr @"$s4main10MySubClassCfD", ptr @"$s4main10MySubClassC3fooyyF", ptr @"$s4main7MyClassC3baryyF", ptr @"$s4main10MySubClassCACycfC" }>
14+
// CHECK: @"$s4main7MyClassCN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfD", ptr null, ptr @"$s4main7MyClassC3fooyyF", ptr @"$s4main7MyClassC3baryyF", ptr @swift_deletedMethodError }>
15+
// CHECK: @"$s4main10MySubClassCN" = {{.*}}<{ ptr, ptr, ptr, ptr, ptr, ptr }> <{ ptr @"$s4main7MyClassCN", ptr @"$s4main10MySubClassCfD", ptr null, ptr @"$s4main10MySubClassC3fooyyF", ptr @"$s4main7MyClassC3baryyF", ptr @"$s4main10MySubClassCACycfC" }>
1616

1717
// CHECK: define {{.*}}void @"$s4main4test1xyAA7MyClassC_tF"(ptr %0)
1818
public func test(x: MyClass) {
1919

2020
x.foo() // goes through the vtable
2121
// CHECK: %1 = load ptr, ptr %0
22-
// CHECK: %2 = getelementptr inbounds ptr, ptr %1, i64 2
22+
// CHECK: %2 = getelementptr inbounds ptr, ptr %1, i64 3
2323
// CHECK: %3 = load ptr, ptr %2
2424
// CHECK: call swiftcc void %3(ptr swiftself %0)
2525

test/embedded/classes-no-stdlib.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
public class MyClass {}
66

7-
// CHECK-DAG: @"$s4main7MyClassCN" = {{.*}}<{ ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfD", ptr @"$s4main7MyClassCACycfC" }>
7+
// CHECK-DAG: @"$s4main7MyClassCN" = {{.*}}<{ ptr, ptr, ptr, ptr }> <{ ptr null, ptr @"$s4main7MyClassCfD", ptr null, ptr @"$s4main7MyClassCACycfC" }>
88
// CHECK-DAG: define {{.*}}ptr @"$s4main7MyClassCfd"
99
// CHECK-DAG: define {{.*}}void @"$s4main7MyClassCfD"
1010
// CHECK-DAG: define {{.*}}ptr @"$s4main7MyClassCACycfC"
@@ -17,7 +17,7 @@ public func foo() -> MyClass {
1717

1818
public class MySubClass: MyClass {}
1919

20-
// CHECK-DAG: @"$s4main10MySubClassCN" = {{.*}}<{ ptr, ptr, ptr }> <{ ptr @"$s4main7MyClassCN", ptr @"$s4main10MySubClassCfD", ptr @"$s4main10MySubClassCACycfC" }>
20+
// CHECK-DAG: @"$s4main10MySubClassCN" = {{.*}}<{ ptr, ptr, ptr, ptr }> <{ ptr @"$s4main7MyClassCN", ptr @"$s4main10MySubClassCfD", ptr null, ptr @"$s4main10MySubClassCACycfC" }>
2121
// CHECK-DAG: define {{.*}}ptr @"$s4main10MySubClassCACycfC"
2222
// CHECK-DAG: define {{.*}}ptr @"$s4main10MySubClassCACycfc"
2323
// CHECK-DAG: define {{.*}}ptr @"$s4main10MySubClassCfd"

test/embedded/init-throwing.swift

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// RUN: %target-run-simple-swift(-enable-experimental-feature Embedded -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
2+
3+
// REQUIRES: swift_in_compiler
4+
// REQUIRES: executable_test
5+
// REQUIRES: optimized_stdlib
6+
// REQUIRES: OS=macosx || OS=linux-gnu
7+
8+
public struct FooError: Error {}
9+
10+
public class PrintingClass {
11+
init() { print("PrintingClass.init") }
12+
deinit { print("PrintingClass.deinit") }
13+
}
14+
15+
public class Foo {
16+
var a: PrintingClass
17+
var b: PrintingClass
18+
init(shouldThrow: Bool) throws(FooError) {
19+
a = PrintingClass()
20+
if shouldThrow { throw FooError() }
21+
b = PrintingClass()
22+
}
23+
}
24+
25+
public class Bar: Foo {
26+
var value: Int = 17
27+
}
28+
29+
public class Wibble: Bar {
30+
var c: PrintingClass = .init()
31+
}
32+
33+
_ = try? Wibble(shouldThrow: true)
34+
print("OK 1")
35+
// CHECK: PrintingClass.init
36+
// CHECK: PrintingClass.init
37+
// CHECK: PrintingClass.deinit
38+
// CHECK: PrintingClass.deinit
39+
// CHECK: OK 1
40+
41+
_ = try? Wibble(shouldThrow: false)
42+
print("OK 2")
43+
// CHECK: PrintingClass.init
44+
// CHECK: PrintingClass.init
45+
// CHECK: PrintingClass.init
46+
// CHECK: PrintingClass.deinit
47+
// CHECK: PrintingClass.deinit
48+
// CHECK: PrintingClass.deinit
49+
// CHECK: OK 2
50+
51+
public class Base {
52+
var baseMember: PrintingClass
53+
init(shouldThrow: Bool) throws(FooError) {
54+
if shouldThrow { throw FooError() }
55+
baseMember = PrintingClass()
56+
}
57+
}
58+
59+
class SubClass: Base {
60+
var subClassMember: PrintingClass = PrintingClass()
61+
override init(shouldThrow: Bool) throws(FooError) {
62+
try super.init(shouldThrow: shouldThrow)
63+
}
64+
}
65+
66+
_ = try? SubClass(shouldThrow: true)
67+
print("OK 3")
68+
// CHECK: PrintingClass.init
69+
// CHECK: PrintingClass.deinit
70+
// CHECK: OK 3
71+
72+
_ = try? SubClass(shouldThrow: false)
73+
print("OK 4")
74+
// CHECK: PrintingClass.init
75+
// CHECK: PrintingClass.init
76+
// CHECK: PrintingClass.deinit
77+
// CHECK: PrintingClass.deinit
78+
// CHECK: OK 4

test/embedded/managed-buffer.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
// REQUIRES: swift_in_compiler
44
// REQUIRES: OS=macosx || OS=linux-gnu
55

6-
// CHECK: @"$s4main8MyBufferCN" = {{.*global.*}} <{ ptr @"$ss13ManagedBufferCySis5UInt8VGN", ptr @"$s4main8MyBufferCfD{{[^"]*}}", ptr @"$s4main8MyBufferC12_doNotCallMeACyt_tcfC{{[^"]*}}" }>
7-
// CHECK: @"$ss13ManagedBufferCySis5UInt8VGN" = {{.*global.*}} <{ ptr null, ptr @"$ss13ManagedBufferCfDSi_s5UInt8VTg5{{[^"]*}}", ptr @"$ss13ManagedBufferC12_doNotCallMeAByxq_Gyt_tcfCSi_s5UInt8VTg5{{[^"]*}}" }>
6+
// CHECK: @"$s4main8MyBufferCN" = {{.*global.*}} <{ ptr @"$ss13ManagedBufferCySis5UInt8VGN", ptr @"$s4main8MyBufferCfD{{[^"]*}}", ptr null, ptr @"$s4main8MyBufferC12_doNotCallMeACyt_tcfC{{[^"]*}}" }>
7+
// CHECK: @"$ss13ManagedBufferCySis5UInt8VGN" = {{.*global.*}} <{ ptr null, ptr @"$ss13ManagedBufferCfDSi_s5UInt8VTg5{{[^"]*}}", ptr null, ptr @"$ss13ManagedBufferC12_doNotCallMeAByxq_Gyt_tcfCSi_s5UInt8VTg5{{[^"]*}}" }>
88
final public class MyBuffer: ManagedBuffer<Int, UInt8> {
99
}
1010

0 commit comments

Comments
 (0)