@@ -366,7 +366,102 @@ intptr_t swift_TupleMirror_count(HeapObject *owner,
366
366
auto Tuple = static_cast <const TupleTypeMetadata *>(type);
367
367
return Tuple->NumElements ;
368
368
}
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);
369
411
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
+
370
465
// / \param owner passed at +1, consumed.
371
466
// / \param value passed unowned.
372
467
extern " C"
@@ -392,11 +487,11 @@ StringMirrorTuple swift_TupleMirror_subscript(intptr_t i,
392
487
auto bytes = reinterpret_cast <const char *>(value);
393
488
auto eltData = reinterpret_cast <const OpaqueValue *>(bytes + elt.Offset );
394
489
395
- // This retain matches the -1 in swift_unsafeReflectAny .
490
+ // This retain matches the -1 in reflect .
396
491
swift_retain (owner);
397
492
398
493
// 'owner' is consumed by this call.
399
- result.second = swift_unsafeReflectAny (owner, eltData, elt.Type );
494
+ result.second = reflect (owner, eltData, elt.Type );
400
495
401
496
return result;
402
497
}
@@ -444,12 +539,12 @@ StringMirrorTuple swift_StructMirror_subscript(intptr_t i,
444
539
445
540
result.first = String (getFieldName (Struct->Description ->Struct .FieldNames , i));
446
541
447
- // This matches the -1 in swift_unsafeReflectAny .
542
+ // This matches the -1 in reflect .
448
543
swift_retain (owner);
449
544
450
545
// 'owner' is consumed by this call.
451
546
assert (!fieldType.isIndirect () && " indirect struct fields not implemented" );
452
- result.second = swift_unsafeReflectAny (owner, fieldData,
547
+ result.second = reflect (owner, fieldData,
453
548
fieldType.getType ());
454
549
455
550
return result;
@@ -553,11 +648,11 @@ StringMirrorTuple swift_EnumMirror_subscript(intptr_t i,
553
648
value = swift_projectBox (const_cast <HeapObject *>(owner));
554
649
}
555
650
556
- // This matches the -1 in swift_unsafeReflectAny .
651
+ // This matches the -1 in reflect .
557
652
swift_retain (owner);
558
653
559
654
result.first = String (getFieldName (Description.CaseNames , tag));
560
- result.second = swift_unsafeReflectAny (owner, value, payloadType);
655
+ result.second = reflect (owner, value, payloadType);
561
656
562
657
return result;
563
658
}
@@ -649,7 +744,7 @@ StringMirrorTuple swift_ClassMirror_subscript(intptr_t i,
649
744
650
745
result.first = String (getFieldName (Clas->getDescription ()->Class .FieldNames , i));
651
746
// 'owner' is consumed by this call.
652
- result.second = swift_unsafeReflectAny (owner, fieldData, fieldType.getType ());
747
+ result.second = reflect (owner, fieldData, fieldType.getType ());
653
748
return result;
654
749
}
655
750
@@ -808,7 +903,7 @@ StringMirrorTuple swift_ObjCMirror_subscript(intptr_t i,
808
903
StringMirrorTuple result;
809
904
result.first = String (name, strlen (name));
810
905
// 'owner' is consumed by this call.
811
- result.second = swift_unsafeReflectAny (owner, ivar, ivarType);
906
+ result.second = reflect (owner, ivar, ivarType);
812
907
return result;
813
908
#else
814
909
// ObjC makes no guarantees about the state of ivars, so we can't safely
@@ -1129,73 +1224,7 @@ static Mirror ObjC_getMirrorForSuperclass(Class sup,
1129
1224
std::tie (T, Self, MirrorWitness) = getImplementationForType (T, value);
1130
1225
Data = {owner, value, T};
1131
1226
}
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);
1174
1227
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
-
1199
1228
} // end anonymous namespace
1200
1229
1201
1230
// / func reflect<T>(x: T) -> Mirror
@@ -1235,32 +1264,3 @@ static Mirror ObjC_getMirrorForSuperclass(Class sup,
1235
1264
T->vw_destroy (value);
1236
1265
return MirrorReturn (result);
1237
1266
}
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