From 71d0a67297da743a5c0c4af877281dc2b28ed020 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sun, 10 Feb 2019 23:57:35 -0500 Subject: [PATCH 1/2] RemoteAST: Fix error existential introspection on Linux --- include/swift/Remote/MetadataReader.h | 31 ++++++++++++--------------- test/RemoteAST/existentials.swift | 2 -- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index 3ad61c68ab2ed..2a6eb93afb40b 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -361,24 +361,21 @@ class MetadataReader { bool isObjC = false; bool isBridged = false; - // If we can determine the Objective-C class name, this is probably an - // error existential with NSError-compatible layout. - std::string ObjCClassName; - if (readObjCClassName(*MetadataAddress, ObjCClassName)) { - if (ObjCClassName == "__SwiftNativeNSError") - isObjC = true; - else + auto Meta = readMetadata(*MetadataAddress); + if (auto ClassMeta = dyn_cast>(Meta)) { + if (ClassMeta->isPureObjC()) { + // If we can determine the Objective-C class name, this is probably an + // error existential with NSError-compatible layout. + std::string ObjCClassName; + if (readObjCClassName(*MetadataAddress, ObjCClassName)) { + if (ObjCClassName == "__SwiftNativeNSError") + isObjC = true; + else + isBridged = true; + } + } else { isBridged = true; - } else { - // Otherwise, we can check to see if this is a class metadata with the - // kind value's least significant bit set, which indicates a pure - // Swift class. - auto Meta = readMetadata(*MetadataAddress); - auto ClassMeta = dyn_cast>(Meta); - if (!ClassMeta) - return None; - - isObjC = ClassMeta->isPureObjC(); + } } if (isBridged) { diff --git a/test/RemoteAST/existentials.swift b/test/RemoteAST/existentials.swift index 6dc7508a0132d..86cc93574eb0b 100644 --- a/test/RemoteAST/existentials.swift +++ b/test/RemoteAST/existentials.swift @@ -1,5 +1,3 @@ -// UNSUPPORTED: linux -// // RUN: %target-swift-remoteast-test %s | %FileCheck %s // REQUIRES: swift-remoteast-test From c20d085bde56d0933e11a1dc9dec3307a9d2f123 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 28 Feb 2019 00:00:35 -0500 Subject: [PATCH 2/2] RemoteAST: Fix Error existential introspection on Linux We don't have tests that look at the instance address on the Swift side, but lldb is going to use this API shortly. --- include/swift/Remote/MetadataReader.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index 2a6eb93afb40b..976a560b1c430 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -410,11 +410,15 @@ class MetadataReader { StoredPointer InstanceAddress = InstanceMetadataAddressAddress + 2 * sizeof(StoredPointer); + // When built with Objective-C interop, the runtime also stores a conformance + // to Hashable and the base type introducing the Hashable conformance. + if (isObjC) + InstanceAddress += 2 * sizeof(StoredPointer); + // Round up to alignment, and we have the start address of the // instance payload. auto AlignmentMask = VWT->getAlignmentMask(); - auto Offset = (sizeof(HeapObject) + AlignmentMask) & ~AlignmentMask; - InstanceAddress += Offset; + InstanceAddress = (InstanceAddress + AlignmentMask) & ~AlignmentMask; return RemoteExistential( RemoteAddress(*InstanceMetadataAddress),