Skip to content

[Runtime] Remove old-style mirrors in ReflectionLegacy.swift. #14678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Feb 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions include/swift/Demangling/Demangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <cassert>
#include <cstdint>
#include "llvm/ADT/StringRef.h"
#include "swift/Runtime/Config.h"

namespace llvm {
class raw_ostream;
Expand Down Expand Up @@ -553,4 +554,30 @@ llvm::StringRef makeSymbolicMangledNameStringRef(const char *base);
} // end namespace Demangle
} // end namespace swift

// NB: This function is not used directly in the Swift codebase, but is
// exported for Xcode support and is used by the sanitizers. Please coordinate
// before changing.
//
/// Demangles a Swift symbol name.
///
/// \param mangledName is the symbol name that needs to be demangled.
/// \param mangledNameLength is the length of the string that should be
/// demangled.
/// \param outputBuffer is the user provided buffer where the demangled name
/// will be placed. If nullptr, a new buffer will be malloced. In that case,
/// the user of this API is responsible for freeing the returned buffer.
/// \param outputBufferSize is the size of the output buffer. If the demangled
/// name does not fit into the outputBuffer, the output will be truncated and
/// the size will be updated, indicating how large the buffer should be.
/// \param flags can be used to select the demangling style. TODO: We should
//// define what these will be.
/// \returns the demangled name. Returns nullptr if the input String is not a
/// Swift mangled name.
SWIFT_RUNTIME_EXPORT
char *swift_demangle(const char *mangledName,
size_t mangledNameLength,
char *outputBuffer,
size_t *outputBufferSize,
uint32_t flags);

#endif // SWIFT_DEMANGLING_DEMANGLE_H
3 changes: 1 addition & 2 deletions stdlib/public/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ set(SWIFTLIB_ESSENTIAL
MutableCollection.swift
NewtypeWrapper.swift.gyb
NormalizedCodeUnitIterator.swift
ObjCMirrors.swift
ObjectIdentifier.swift
Optional.swift
OptionSet.swift
Expand All @@ -101,7 +100,7 @@ set(SWIFTLIB_ESSENTIAL
RandomAccessCollection.swift
Range.swift
RangeReplaceableCollection.swift
ReflectionLegacy.swift
ReflectionMirror.swift
Repeat.swift
REPL.swift
Reverse.swift
Expand Down
5 changes: 2 additions & 3 deletions stdlib/public/core/GroupInfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,8 @@
"Dump.swift",
"Mirror.swift",
"Mirrors.swift",
"ObjCMirrors.swift",
"ObjectIdentifier.swift",
"ReflectionLegacy.swift"
"ReflectionMirror.swift",
"ObjectIdentifier.swift"
],
"Math": [
"SetAlgebra.swift",
Expand Down
199 changes: 12 additions & 187 deletions stdlib/public/core/Mirror.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ public struct Mirror {
if case let customized as CustomReflectable = subject {
self = customized.customMirror
} else {
self = Mirror(
legacy: _reflect(subject),
subjectType: type(of: subject))
self = Mirror(internalReflecting: subject)
}
}

Expand Down Expand Up @@ -164,29 +162,6 @@ public struct Mirror {
@_versioned // FIXME(sil-serialize-all)
internal static func _noSuperclassMirror() -> Mirror? { return nil }

/// Returns the legacy mirror representing the part of `subject`
/// corresponding to the superclass of `staticSubclass`.
@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal static func _legacyMirror(
_ subject: AnyObject, asClass targetSuperclass: AnyClass) -> _Mirror? {

// get a legacy mirror and the most-derived type
var cls: AnyClass = type(of: subject)
var clsMirror = _reflect(subject)

// Walk up the chain of mirrors/classes until we find staticSubclass
while let superclass: AnyClass = _getSuperclass(cls) {
guard let superclassMirror = clsMirror._superMirror() else { break }

if superclass == targetSuperclass { return superclassMirror }

clsMirror = superclassMirror
cls = superclass
}
return nil
}

@_semantics("optimize.sil.specialize.generic.never")
@inline(never)
@_inlineable // FIXME(sil-serialize-all)
Expand All @@ -201,14 +176,19 @@ public struct Mirror {
switch ancestorRepresentation {
case .generated:
return {
self._legacyMirror(_unsafeDowncastToAnyObject(fromAny: subject), asClass: superclass).map {
Mirror(legacy: $0, subjectType: superclass)
}
Mirror(internalReflecting: subject, subjectType: superclass)
}
case .customized(let makeAncestor):
return {
Mirror(_unsafeDowncastToAnyObject(fromAny: subject), subjectClass: superclass,
ancestor: makeAncestor())
let ancestor = makeAncestor()
if superclass == ancestor.subjectType
|| ancestor._defaultDescendantRepresentation == .suppressed {
return ancestor
} else {
return Mirror(internalReflecting: subject,
subjectType: superclass,
customAncestor: ancestor)
}
}
case .suppressed:
break
Expand Down Expand Up @@ -503,161 +483,6 @@ extension Mirror {
}
}

//===--- Legacy _Mirror Support -------------------------------------------===//
extension Mirror.DisplayStyle {
/// Construct from a legacy `_MirrorDisposition`
@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal init?(legacy: _MirrorDisposition) {
switch legacy {
case .`struct`: self = .`struct`
case .`class`: self = .`class`
case .`enum`: self = .`enum`
case .tuple: self = .tuple
case .aggregate: return nil
case .indexContainer: self = .collection
case .keyContainer: self = .dictionary
case .membershipContainer: self = .`set`
case .container: preconditionFailure("unused!")
case .optional: self = .optional
case .objCObject: self = .`class`
}
}
}

@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal func _isClassSuperMirror(_ t: Any.Type) -> Bool {
#if _runtime(_ObjC)
return t == _ClassSuperMirror.self || t == _ObjCSuperMirror.self
#else
return t == _ClassSuperMirror.self
#endif
}

extension _Mirror {
@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal func _superMirror() -> _Mirror? {
if self.count > 0 {
let childMirror = self[0].1
if _isClassSuperMirror(type(of: childMirror)) {
return childMirror
}
}
return nil
}
}

/// When constructed using the legacy reflection infrastructure, the
/// resulting `Mirror`'s `children` collection will always be
/// upgradable to `AnyRandomAccessCollection` even if it doesn't
/// exhibit appropriate performance. To avoid this pitfall, convert
/// mirrors to use the new style, which only present forward
/// traversal in general.
internal extension Mirror {
/// An adapter that represents a legacy `_Mirror`'s children as
/// a `Collection` with integer `Index`. Note that the performance
/// characteristics of the underlying `_Mirror` may not be
/// appropriate for random access! To avoid this pitfall, convert
/// mirrors to use the new style, which only present forward
/// traversal in general.
@_fixed_layout // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal struct LegacyChildren : RandomAccessCollection {
internal typealias Indices = Range<Int>

@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal init(_ oldMirror: _Mirror) {
self._oldMirror = oldMirror
}

@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal var startIndex: Int {
return _oldMirror._superMirror() == nil ? 0 : 1
}

@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal var endIndex: Int { return _oldMirror.count }

@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal subscript(position: Int) -> Child {
let (label, childMirror) = _oldMirror[position]
return (label: label, value: childMirror.value)
}

@_versioned // FIXME(sil-serialize-all)
internal let _oldMirror: _Mirror
}

/// Initialize for a view of `subject` as `subjectClass`.
///
/// - parameter ancestor: A Mirror for a (non-strict) ancestor of
/// `subjectClass`, to be injected into the resulting hierarchy.
///
/// - parameter legacy: Either `nil`, or a legacy mirror for `subject`
/// as `subjectClass`.
@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal init(
_ subject: AnyObject,
subjectClass: AnyClass,
ancestor: Mirror,
legacy legacyMirror: _Mirror? = nil
) {
if ancestor.subjectType == subjectClass
|| ancestor._defaultDescendantRepresentation == .suppressed {
self = ancestor
}
else {
let legacyMirror = legacyMirror ?? Mirror._legacyMirror(
subject, asClass: subjectClass)!

self = Mirror(
legacy: legacyMirror,
subjectType: subjectClass,
makeSuperclassMirror: {
_getSuperclass(subjectClass).map {
Mirror(
subject,
subjectClass: $0,
ancestor: ancestor,
legacy: legacyMirror._superMirror())
}
})
}
}

@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
internal init(
legacy legacyMirror: _Mirror,
subjectType: Any.Type,
makeSuperclassMirror: (() -> Mirror?)? = nil
) {
if let makeSuperclassMirror = makeSuperclassMirror {
self._makeSuperclassMirror = makeSuperclassMirror
}
else if let subjectSuperclass = _getSuperclass(subjectType) {
self._makeSuperclassMirror = {
legacyMirror._superMirror().map {
Mirror(legacy: $0, subjectType: subjectSuperclass) }
}
}
else {
self._makeSuperclassMirror = Mirror._noSuperclassMirror
}
self.subjectType = subjectType
self.children = Children(LegacyChildren(legacyMirror))
self.displayStyle = DisplayStyle(legacy: legacyMirror.disposition)
self._defaultDescendantRepresentation = .generated
}
}

//===--- QuickLooks -------------------------------------------------------===//

/// The sum of types that can be used as a Quick Look representation.
Expand Down Expand Up @@ -769,7 +594,7 @@ extension PlaygroundQuickLook {
self = customized._defaultCustomPlaygroundQuickLook
}
else {
if let q = _reflect(subject).quickLookObject {
if let q = Mirror.quickLookObject(subject) {
self = q
}
else {
Expand Down
Loading