[embedded] Handle NULL IVarDestroyers, expand test

This commit is contained in:
Kuba Mracek
2024-03-26 21:14:21 -07:00
parent b8bd832fba
commit 37d9be636a
3 changed files with 22 additions and 8 deletions

View File

@@ -63,13 +63,15 @@ _swift_embedded_invoke_heap_object_destroy(void *object) {
}
static inline void
_swift_embedded_invoke_heap_object_ivardestroyer(void *object, void *metadata) {
_swift_embedded_invoke_heap_object_optional_ivardestroyer(void *object, void *metadata) {
void **ivardestroyer_location = &((void **)metadata)[2];
if (*ivardestroyer_location) {
#if __has_feature(ptrauth_calls)
(*(HeapObjectDestroyer __ptrauth(0, 1, 0xbbbf) *)ivardestroyer_location)(object);
#else
(*(HeapObjectDestroyer *)ivardestroyer_location)(object);
#endif
}
}
static inline void *_swift_embedded_get_heap_object_metadata_pointer(void *object) {

View File

@@ -24,8 +24,8 @@ public struct ClassMetadata {
// There is no way to express the actual calling convention on this
// function (swiftcc with 'self') currently, so let's use UnsafeRawPointer
// and a helper function in C (_swift_embedded_invoke_heap_object_ivardestroyer).
var ivarDestroyer: UnsafeRawPointer
// and a helper function in C (_swift_embedded_invoke_heap_object_optional_ivardestroyer).
var ivarDestroyer: UnsafeRawPointer?
}
public struct HeapObject {
@@ -129,7 +129,7 @@ public func swift_deallocPartialClassInstance(object: Builtin.RawPointer, metada
func swift_deallocPartialClassInstance(object: UnsafeMutablePointer<HeapObject>, metadata: UnsafeMutablePointer<ClassMetadata>, allocatedSize: Int, allocatedAlignMask: Int) {
var classMetadata = _swift_embedded_get_heap_object_metadata_pointer(object).assumingMemoryBound(to: ClassMetadata.self)
while classMetadata != metadata {
_swift_embedded_invoke_heap_object_ivardestroyer(object, classMetadata)
_swift_embedded_invoke_heap_object_optional_ivardestroyer(object, classMetadata)
guard let superclassMetadata = classMetadata.pointee.superclassMetadata else { break }
classMetadata = superclassMetadata
}

View File

@@ -22,16 +22,28 @@ public class Foo {
}
}
_ = try? Foo(shouldThrow: true)
public class Bar: Foo {
var value: Int = 17
}
public class Wibble: Bar {
var c: PrintingClass = .init()
}
_ = try? Wibble(shouldThrow: true)
print("OK 1")
// CHECK: PrintingClass.init
// CHECK: PrintingClass.init
// CHECK: PrintingClass.deinit
// CHECK: PrintingClass.deinit
// CHECK: OK 1
_ = try? Foo(shouldThrow: false)
_ = try? Wibble(shouldThrow: false)
print("OK 2")
// CHECK: PrintingClass.init
// CHECK: PrintingClass.init
// CHECK: PrintingClass.init
// CHECK: PrintingClass.deinit
// CHECK: PrintingClass.deinit
// CHECK: PrintingClass.deinit
// CHECK: OK 2