Skip to content

Commit fed7f79

Browse files
committed
Runtime: Static-ize swift_unsafeReflectAny.
The _unsafeReflect entry point never ended up getting used on the Swift side, so don't export it, and remove the _silgen_name'd declaration.
1 parent 124b0e4 commit fed7f79

File tree

3 files changed

+103
-125
lines changed

3 files changed

+103
-125
lines changed

include/swift/Runtime/Reflection.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,6 @@ struct MirrorReturn {
4949
/// in the runtime that structurally reflects values of any type.
5050
extern "C" MirrorReturn
5151
swift_reflectAny(OpaqueValue *value, const Metadata *T);
52-
53-
/// func unsafeReflect<T>(owner: Builtin.NativeObject,
54-
/// x: UnsafeMutablePointer<T>) -> Mirror
55-
///
56-
/// Produce a mirror for any value. If the value's type conforms to _Reflectable,
57-
/// invoke its _getMirror() method; otherwise, fall back to an implementation
58-
/// in the runtime that structurally reflects values of any type.
59-
extern "C" MirrorReturn
60-
swift_unsafeReflectAny(HeapObject *owner,
61-
const OpaqueValue *value, const Metadata *T);
6252

6353
#pragma clang diagnostic pop
6454

stdlib/public/core/Reflection.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -144,18 +144,6 @@ func _getSummary<T>(out: UnsafeMutablePointer<String>, x: T) {
144144
@_silgen_name("swift_reflectAny")
145145
public func _reflect<T>(x: T) -> _MirrorType
146146

147-
/// Unsafely produce a mirror for a value in memory whose lifetime is
148-
/// guaranteed by holding a strong reference to a heap object.
149-
/// This lets containers with heap storage vend mirrors for their elements
150-
/// without unnecessary copying of the underlying value.
151-
@warn_unused_result
152-
@_silgen_name("swift_unsafeReflectAny")
153-
internal func _unsafeReflect<T>(
154-
owner: Builtin.NativeObject,
155-
ptr: UnsafeMutablePointer<T>
156-
) -> _MirrorType
157-
158-
159147
/// Dump an object's contents using its mirror to the specified output stream.
160148
public func dump<T, TargetStream : OutputStreamType>(
161149
x: T, inout _ targetStream: TargetStream,

stdlib/public/runtime/Reflection.mm

Lines changed: 103 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,102 @@ intptr_t swift_TupleMirror_count(HeapObject *owner,
366366
auto Tuple = static_cast<const TupleTypeMetadata *>(type);
367367
return Tuple->NumElements;
368368
}
369+
370+
static std::tuple<const _ReflectableWitnessTable *, const Metadata *,
371+
const OpaqueValue *>
372+
getReflectableConformance(const Metadata *T, const OpaqueValue *Value) {
373+
recur:
374+
// If the value is an existential container, look through it to reflect the
375+
// contained value.
376+
switch (T->getKind()) {
377+
case MetadataKind::Tuple:
378+
case MetadataKind::Struct:
379+
case MetadataKind::ForeignClass:
380+
case MetadataKind::ObjCClassWrapper:
381+
case MetadataKind::Class:
382+
case MetadataKind::Opaque:
383+
case MetadataKind::Enum:
384+
case MetadataKind::Function:
385+
case MetadataKind::Metatype:
386+
break;
387+
388+
case MetadataKind::Existential: {
389+
auto existential
390+
= static_cast<const ExistentialTypeMetadata *>(T);
391+
392+
// If the existential happens to include the _Reflectable protocol, use
393+
// the witness table from the container.
394+
unsigned wtOffset = 0;
395+
for (unsigned i = 0; i < existential->Protocols.NumProtocols; ++i) {
396+
if (existential->Protocols[i] == &_TMps12_Reflectable) {
397+
return std::make_tuple(
398+
reinterpret_cast<const _ReflectableWitnessTable*>(
399+
existential->getWitnessTable(Value, wtOffset)),
400+
existential->getDynamicType(Value),
401+
existential->projectValue(Value));
402+
}
403+
if (existential->Protocols[i]->Flags.needsWitnessTable())
404+
++wtOffset;
405+
}
406+
407+
// Otherwise, unwrap the existential container and do a runtime lookup on
408+
// its contained value as usual.
409+
T = existential->getDynamicType(Value);
410+
Value = existential->projectValue(Value);
369411

412+
// Existential containers can end up nested in some cases due to generic
413+
// abstraction barriers. Recur in case we have a nested existential.
414+
goto recur;
415+
}
416+
case MetadataKind::ExistentialMetatype:
417+
// TODO: Should look through existential metatypes too, but it doesn't
418+
// really matter yet since we don't have any special mirror behavior for
419+
// concrete metatypes yet.
420+
break;
421+
422+
// Types can't have these kinds.
423+
case MetadataKind::HeapLocalVariable:
424+
case MetadataKind::HeapGenericLocalVariable:
425+
case MetadataKind::ErrorObject:
426+
swift::crash("Swift mirror lookup failure");
427+
}
428+
429+
return std::make_tuple(
430+
reinterpret_cast<const _ReflectableWitnessTable*>(
431+
swift_conformsToProtocol(T, &_TMps12_Reflectable)),
432+
T,
433+
Value);
434+
}
435+
436+
/// Produce a mirror for any value, like swift_reflectAny, but do not consume
437+
/// the value, so we can produce a mirror for a subobject of a value already
438+
/// owned by a mirror.
439+
///
440+
/// \param owner passed at +1, consumed.
441+
/// \param value passed unowned.
442+
static Mirror reflect(HeapObject *owner,
443+
const OpaqueValue *value,
444+
const Metadata *T) {
445+
const _ReflectableWitnessTable *witness;
446+
const Metadata *mirrorType;
447+
const OpaqueValue *mirrorValue;
448+
std::tie(witness, mirrorType, mirrorValue)
449+
= getReflectableConformance(T, value);
450+
451+
// Use the _Reflectable conformance if the object has one.
452+
if (witness) {
453+
auto result =
454+
witness->getMirror(const_cast<OpaqueValue*>(mirrorValue), mirrorType);
455+
swift_release(owner);
456+
return MirrorReturn(result);
457+
}
458+
// Otherwise, fall back to MagicMirror.
459+
// Consumes 'owner'.
460+
Mirror result;
461+
::new (&result) MagicMirror(owner, mirrorValue, mirrorType);
462+
return result;
463+
}
464+
370465
/// \param owner passed at +1, consumed.
371466
/// \param value passed unowned.
372467
extern "C"
@@ -392,11 +487,11 @@ StringMirrorTuple swift_TupleMirror_subscript(intptr_t i,
392487
auto bytes = reinterpret_cast<const char*>(value);
393488
auto eltData = reinterpret_cast<const OpaqueValue *>(bytes + elt.Offset);
394489

395-
// This retain matches the -1 in swift_unsafeReflectAny.
490+
// This retain matches the -1 in reflect.
396491
swift_retain(owner);
397492

398493
// 'owner' is consumed by this call.
399-
result.second = swift_unsafeReflectAny(owner, eltData, elt.Type);
494+
result.second = reflect(owner, eltData, elt.Type);
400495

401496
return result;
402497
}
@@ -444,12 +539,12 @@ StringMirrorTuple swift_StructMirror_subscript(intptr_t i,
444539

445540
result.first = String(getFieldName(Struct->Description->Struct.FieldNames, i));
446541

447-
// This matches the -1 in swift_unsafeReflectAny.
542+
// This matches the -1 in reflect.
448543
swift_retain(owner);
449544

450545
// 'owner' is consumed by this call.
451546
assert(!fieldType.isIndirect() && "indirect struct fields not implemented");
452-
result.second = swift_unsafeReflectAny(owner, fieldData,
547+
result.second = reflect(owner, fieldData,
453548
fieldType.getType());
454549

455550
return result;
@@ -553,11 +648,11 @@ StringMirrorTuple swift_EnumMirror_subscript(intptr_t i,
553648
value = swift_projectBox(const_cast<HeapObject *>(owner));
554649
}
555650

556-
// This matches the -1 in swift_unsafeReflectAny.
651+
// This matches the -1 in reflect.
557652
swift_retain(owner);
558653

559654
result.first = String(getFieldName(Description.CaseNames, tag));
560-
result.second = swift_unsafeReflectAny(owner, value, payloadType);
655+
result.second = reflect(owner, value, payloadType);
561656

562657
return result;
563658
}
@@ -649,7 +744,7 @@ StringMirrorTuple swift_ClassMirror_subscript(intptr_t i,
649744

650745
result.first = String(getFieldName(Clas->getDescription()->Class.FieldNames, i));
651746
// 'owner' is consumed by this call.
652-
result.second = swift_unsafeReflectAny(owner, fieldData, fieldType.getType());
747+
result.second = reflect(owner, fieldData, fieldType.getType());
653748
return result;
654749
}
655750

@@ -808,7 +903,7 @@ StringMirrorTuple swift_ObjCMirror_subscript(intptr_t i,
808903
StringMirrorTuple result;
809904
result.first = String(name, strlen(name));
810905
// 'owner' is consumed by this call.
811-
result.second = swift_unsafeReflectAny(owner, ivar, ivarType);
906+
result.second = reflect(owner, ivar, ivarType);
812907
return result;
813908
#else
814909
// ObjC makes no guarantees about the state of ivars, so we can't safely
@@ -1129,73 +1224,7 @@ static Mirror ObjC_getMirrorForSuperclass(Class sup,
11291224
std::tie(T, Self, MirrorWitness) = getImplementationForType(T, value);
11301225
Data = {owner, value, T};
11311226
}
1132-
1133-
static std::tuple<const _ReflectableWitnessTable *, const Metadata *,
1134-
const OpaqueValue *>
1135-
getReflectableConformance(const Metadata *T, const OpaqueValue *Value) {
1136-
recur:
1137-
// If the value is an existential container, look through it to reflect the
1138-
// contained value.
1139-
switch (T->getKind()) {
1140-
case MetadataKind::Tuple:
1141-
case MetadataKind::Struct:
1142-
case MetadataKind::ForeignClass:
1143-
case MetadataKind::ObjCClassWrapper:
1144-
case MetadataKind::Class:
1145-
case MetadataKind::Opaque:
1146-
case MetadataKind::Enum:
1147-
case MetadataKind::Function:
1148-
case MetadataKind::Metatype:
1149-
break;
1150-
1151-
case MetadataKind::Existential: {
1152-
auto existential
1153-
= static_cast<const ExistentialTypeMetadata *>(T);
1154-
1155-
// If the existential happens to include the _Reflectable protocol, use
1156-
// the witness table from the container.
1157-
unsigned wtOffset = 0;
1158-
for (unsigned i = 0; i < existential->Protocols.NumProtocols; ++i) {
1159-
if (existential->Protocols[i] == &_TMps12_Reflectable) {
1160-
return std::make_tuple(
1161-
reinterpret_cast<const _ReflectableWitnessTable*>(
1162-
existential->getWitnessTable(Value, wtOffset)),
1163-
existential->getDynamicType(Value),
1164-
existential->projectValue(Value));
1165-
}
1166-
if (existential->Protocols[i]->Flags.needsWitnessTable())
1167-
++wtOffset;
1168-
}
1169-
1170-
// Otherwise, unwrap the existential container and do a runtime lookup on
1171-
// its contained value as usual.
1172-
T = existential->getDynamicType(Value);
1173-
Value = existential->projectValue(Value);
11741227

1175-
// Existential containers can end up nested in some cases due to generic
1176-
// abstraction barriers. Recur in case we have a nested existential.
1177-
goto recur;
1178-
}
1179-
case MetadataKind::ExistentialMetatype:
1180-
// TODO: Should look through existential metatypes too, but it doesn't
1181-
// really matter yet since we don't have any special mirror behavior for
1182-
// concrete metatypes yet.
1183-
break;
1184-
1185-
// Types can't have these kinds.
1186-
case MetadataKind::HeapLocalVariable:
1187-
case MetadataKind::HeapGenericLocalVariable:
1188-
case MetadataKind::ErrorObject:
1189-
swift::crash("Swift mirror lookup failure");
1190-
}
1191-
1192-
return std::make_tuple(
1193-
reinterpret_cast<const _ReflectableWitnessTable*>(
1194-
swift_conformsToProtocol(T, &_TMps12_Reflectable)),
1195-
T,
1196-
Value);
1197-
}
1198-
11991228
} // end anonymous namespace
12001229

12011230
/// func reflect<T>(x: T) -> Mirror
@@ -1235,32 +1264,3 @@ static Mirror ObjC_getMirrorForSuperclass(Class sup,
12351264
T->vw_destroy(value);
12361265
return MirrorReturn(result);
12371266
}
1238-
1239-
/// Produce a mirror for any value, like swift_reflectAny, but do not consume
1240-
/// the value, so we can produce a mirror for a subobject of a value already
1241-
/// owned by a mirror.
1242-
///
1243-
/// \param owner passed at +1, consumed.
1244-
/// \param value passed unowned.
1245-
MirrorReturn swift::swift_unsafeReflectAny(HeapObject *owner,
1246-
const OpaqueValue *value,
1247-
const Metadata *T) {
1248-
const _ReflectableWitnessTable *witness;
1249-
const Metadata *mirrorType;
1250-
const OpaqueValue *mirrorValue;
1251-
std::tie(witness, mirrorType, mirrorValue)
1252-
= getReflectableConformance(T, value);
1253-
1254-
// Use the _Reflectable conformance if the object has one.
1255-
if (witness) {
1256-
auto result =
1257-
witness->getMirror(const_cast<OpaqueValue*>(mirrorValue), mirrorType);
1258-
swift_release(owner);
1259-
return MirrorReturn(result);
1260-
}
1261-
// Otherwise, fall back to MagicMirror.
1262-
// Consumes 'owner'.
1263-
Mirror result;
1264-
::new (&result) MagicMirror(owner, mirrorValue, mirrorType);
1265-
return MirrorReturn(result);
1266-
}

0 commit comments

Comments
 (0)