Skip to content

Commit 905a6de

Browse files
committed
RemoteAST: Clean up use of std::pair and std::tuple for opened existentials with named structs
1 parent 56a74c4 commit 905a6de

File tree

5 files changed

+107
-77
lines changed

5 files changed

+107
-77
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -520,15 +520,14 @@ class ReflectionContext
520520
readMetadataAndValueOpaqueExistential(ExistentialAddress);
521521
if (!OptMetaAndValue)
522522
return false;
523-
RemoteAddress MetadataAddress = OptMetaAndValue->first;
524-
RemoteAddress ValueAddress = OptMetaAndValue->second;
525523

526-
auto InstanceTR = readTypeFromMetadata(MetadataAddress.getAddressData());
524+
auto InstanceTR = readTypeFromMetadata(
525+
OptMetaAndValue->MetadataAddress.getAddressData());
527526
if (!InstanceTR)
528527
return false;
529528

530529
*OutInstanceTR = InstanceTR;
531-
*OutInstanceAddress = ValueAddress;
530+
*OutInstanceAddress = OptMetaAndValue->PayloadAddress;
532531
return true;
533532
}
534533
case RecordKind::ErrorExistential: {
@@ -537,17 +536,15 @@ class ReflectionContext
537536
if (!OptMetaAndValue)
538537
return false;
539538

540-
RemoteAddress InstanceMetadataAddress = std::get<0>(*OptMetaAndValue);
541-
RemoteAddress InstanceAddress = std::get<1>(*OptMetaAndValue);
542-
// FIXME: Check third value, 'isBridged'
539+
// FIXME: Check third value, 'IsBridgedError'
543540

544-
auto InstanceTR =
545-
readTypeFromMetadata(InstanceMetadataAddress.getAddressData());
541+
auto InstanceTR = readTypeFromMetadata(
542+
OptMetaAndValue->MetadataAddress.getAddressData());
546543
if (!InstanceTR)
547544
return false;
548545

549546
*OutInstanceTR = InstanceTR;
550-
*OutInstanceAddress = RemoteAddress(InstanceAddress);
547+
*OutInstanceAddress = OptMetaAndValue->PayloadAddress;
551548
return true;
552549
}
553550
default:

include/swift/Remote/MetadataReader.h

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,26 @@ struct delete_with_free {
8686
}
8787
};
8888

89+
/// A structure representing an opened existential type.
90+
struct RemoteExistential {
91+
/// The payload's concrete type metadata.
92+
RemoteAddress MetadataAddress;
93+
94+
/// The address of the payload value.
95+
RemoteAddress PayloadAddress;
96+
97+
/// True if this is an NSError instance transparently bridged to an Error
98+
/// existential.
99+
bool IsBridgedError;
100+
101+
RemoteExistential(RemoteAddress MetadataAddress,
102+
RemoteAddress PayloadAddress,
103+
bool IsBridgedError=false)
104+
: MetadataAddress(MetadataAddress),
105+
PayloadAddress(PayloadAddress),
106+
IsBridgedError(IsBridgedError) {}
107+
};
108+
89109
/// A generic reader of metadata.
90110
///
91111
/// BuilderType must implement a particular interface which is currently
@@ -330,7 +350,7 @@ class MetadataReader {
330350
/// pointer to its metadata address, its value address, and whether this
331351
/// is a toll-free-bridged NSError or an actual Error existential wrapper
332352
/// around a native Swift value.
333-
Optional<std::tuple<RemoteAddress, RemoteAddress, bool>>
353+
Optional<RemoteExistential>
334354
readMetadataAndValueErrorExistential(RemoteAddress ExistentialAddress) {
335355
// An pointer to an error existential is always an heap object.
336356
auto MetadataAddress =
@@ -363,10 +383,9 @@ class MetadataReader {
363383

364384
if (isBridged) {
365385
// NSError instances don't need to be unwrapped.
366-
return Optional<std::tuple<RemoteAddress, RemoteAddress, bool>>(
367-
{RemoteAddress(*MetadataAddress),
368-
ExistentialAddress,
369-
isBridged});
386+
return RemoteExistential(RemoteAddress(*MetadataAddress),
387+
ExistentialAddress,
388+
isBridged);
370389
}
371390

372391
// In addition to the isa pointer and two 32-bit reference counts, if the
@@ -400,15 +419,15 @@ class MetadataReader {
400419
auto Offset = (sizeof(HeapObject) + AlignmentMask) & ~AlignmentMask;
401420
InstanceAddress += Offset;
402421

403-
return Optional<std::tuple<RemoteAddress, RemoteAddress, bool>>(
404-
{RemoteAddress(*InstanceMetadataAddress),
405-
RemoteAddress(InstanceAddress),
406-
isBridged});
422+
return RemoteExistential(
423+
RemoteAddress(*InstanceMetadataAddress),
424+
RemoteAddress(InstanceAddress),
425+
isBridged);
407426
}
408427

409428
/// Given a known-opaque existential, attemp to discover the pointer to its
410429
/// metadata address and its value.
411-
Optional<std::pair<RemoteAddress, RemoteAddress>>
430+
Optional<RemoteExistential>
412431
readMetadataAndValueOpaqueExistential(RemoteAddress ExistentialAddress) {
413432
// OpaqueExistentialContainer is the layout of an opaque existential.
414433
// `Type` is the pointer to the metadata.
@@ -428,8 +447,8 @@ class MetadataReader {
428447
// Inline representation (the value fits in the existential container).
429448
// So, the value starts at the first word of the container.
430449
if (VWT->isValueInline())
431-
return Optional<std::pair<RemoteAddress, RemoteAddress>>(
432-
{RemoteAddress(MetadataAddress), ExistentialAddress});
450+
return RemoteExistential(RemoteAddress(MetadataAddress),
451+
ExistentialAddress);
433452

434453
// Non-inline (box'ed) representation.
435454
// The first word of the container stores the address to the box.
@@ -440,8 +459,8 @@ class MetadataReader {
440459
auto AlignmentMask = VWT->getAlignmentMask();
441460
auto Offset = (sizeof(HeapObject) + AlignmentMask) & ~AlignmentMask;
442461
auto StartOfValue = BoxAddress + Offset;
443-
return Optional<std::pair<RemoteAddress, RemoteAddress>>(
444-
{RemoteAddress(MetadataAddress), RemoteAddress(StartOfValue)});
462+
return RemoteExistential(RemoteAddress(MetadataAddress),
463+
RemoteAddress(StartOfValue));
445464
}
446465

447466
/// Read a protocol from a reference to said protocol.

include/swift/RemoteAST/RemoteAST.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/Remote/MemoryReader.h"
2424
#include "swift/Basic/LLVM.h"
2525
#include "swift/ABI/MetadataValues.h"
26+
#include "swift/AST/Type.h"
2627
#include "llvm/ADT/Optional.h"
2728
#include "llvm/ADT/StringRef.h"
2829

@@ -31,7 +32,6 @@
3132
namespace swift {
3233
class ASTContext;
3334
class NominalTypeDecl;
34-
class Type;
3535

3636
namespace remoteAST {
3737

@@ -136,7 +136,20 @@ class Result {
136136
}
137137
};
138138

139-
using OpenedExistential = Result<std::pair<Type, remote::RemoteAddress>>;
139+
/// A structure representing an opened existential value.
140+
struct OpenedExistential {
141+
/// The concrete type of the value inside the existential.
142+
Type InstanceType;
143+
144+
/// The address of the payload.
145+
///
146+
/// Note: If the concrete type is a class type, this is the address of the
147+
/// instance and not the address of the reference to the instance.
148+
remote::RemoteAddress PayloadAddress;
149+
150+
OpenedExistential(Type InstanceType, remote::RemoteAddress PayloadAddress)
151+
: InstanceType(InstanceType), PayloadAddress(PayloadAddress) {}
152+
};
140153

141154
/// A context for performing an operation relating the remote process with
142155
/// the AST. This may be discarded and recreated at any time without danger,
@@ -217,14 +230,14 @@ class RemoteASTContext {
217230
/// Resolve the dynamic type and the value address of an error existential
218231
/// object, Unlike getDynamicTypeAndAddressForExistential(), this function
219232
/// takes the address of the instance and not the address of the reference.
220-
OpenedExistential
233+
Result<OpenedExistential>
221234
getDynamicTypeAndAddressForError(remote::RemoteAddress object);
222235

223236
/// Given an existential and its static type, resolve its dynamic
224237
/// type and address. A single step of unwrapping is performed, i.e. if the
225238
/// value stored inside the existential is itself an existential, the
226239
/// caller can decide whether to iterate itself.
227-
OpenedExistential
240+
Result<OpenedExistential>
228241
getDynamicTypeAndAddressForExistential(remote::RemoteAddress address,
229242
Type staticType);
230243
};

lib/RemoteAST/RemoteAST.cpp

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ class RemoteASTContextImpl {
104104
getDeclForRemoteNominalTypeDescriptor(RemoteAddress descriptor) = 0;
105105
virtual Result<RemoteAddress>
106106
getHeapMetadataForObject(RemoteAddress object) = 0;
107-
virtual OpenedExistential
107+
virtual Result<OpenedExistential>
108108
getDynamicTypeAndAddressForError(RemoteAddress object) = 0;
109-
virtual OpenedExistential
109+
virtual Result<OpenedExistential>
110110
getDynamicTypeAndAddressForExistential(RemoteAddress object,
111111
Type staticType) = 0;
112112

@@ -478,89 +478,89 @@ class RemoteASTContextConcreteImpl final : public RemoteASTContextImpl {
478478
return getFailure<RemoteAddress>();
479479
}
480480

481-
OpenedExistential
481+
Result<OpenedExistential>
482482
getDynamicTypeAndAddressClassExistential(RemoteAddress object) {
483483
auto pointerval = Reader.readPointerValue(object.getAddressData());
484484
if (!pointerval)
485-
return getFailure<std::pair<Type, RemoteAddress>>();
485+
return getFailure<OpenedExistential>();
486486
auto result = Reader.readMetadataFromInstance(*pointerval);
487487
if (!result)
488-
return getFailure<std::pair<Type, RemoteAddress>>();
488+
return getFailure<OpenedExistential>();
489489
auto typeResult = Reader.readTypeFromMetadata(result.getValue());
490490
if (!typeResult)
491-
return getFailure<std::pair<Type, RemoteAddress>>();
492-
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
493-
RemoteAddress(*pointerval));
491+
return getFailure<OpenedExistential>();
492+
return OpenedExistential(std::move(typeResult),
493+
RemoteAddress(*pointerval));
494494
}
495495

496-
OpenedExistential
496+
Result<OpenedExistential>
497497
getDynamicTypeAndAddressErrorExistential(RemoteAddress object,
498498
bool dereference=true) {
499499
if (dereference) {
500500
auto pointerval = Reader.readPointerValue(object.getAddressData());
501501
if (!pointerval)
502-
return getFailure<std::pair<Type, RemoteAddress>>();
502+
return getFailure<OpenedExistential>();
503503
object = RemoteAddress(*pointerval);
504504
}
505505

506506
auto result =
507507
Reader.readMetadataAndValueErrorExistential(object);
508508
if (!result)
509-
return getFailure<std::pair<Type, RemoteAddress>>();
510-
511-
RemoteAddress metadataAddress = std::get<0>(*result);
512-
RemoteAddress valueAddress = std::get<1>(*result);
513-
bool isBridged = std::get<2>(*result);
509+
return getFailure<OpenedExistential>();
514510

515511
auto typeResult =
516-
Reader.readTypeFromMetadata(metadataAddress.getAddressData());
512+
Reader.readTypeFromMetadata(result->MetadataAddress.getAddressData());
517513
if (!typeResult)
518-
return getFailure<std::pair<Type, RemoteAddress>>();
514+
return getFailure<OpenedExistential>();
515+
519516

520517
// When the existential wraps a class type, LLDB expects that the
521518
// address returned is the class instance itself and not the address
522519
// of the reference.
523-
if (!isBridged && typeResult->getClassOrBoundGenericClass()) {
524-
auto pointerval = Reader.readPointerValue(valueAddress.getAddressData());
520+
auto payloadAddress = result->PayloadAddress;
521+
if (!result->IsBridgedError &&
522+
typeResult->getClassOrBoundGenericClass()) {
523+
auto pointerval = Reader.readPointerValue(
524+
payloadAddress.getAddressData());
525525
if (!pointerval)
526-
return getFailure<std::pair<Type, RemoteAddress>>();
526+
return getFailure<OpenedExistential>();
527527

528-
valueAddress = RemoteAddress(*pointerval);
528+
payloadAddress = RemoteAddress(*pointerval);
529529
}
530530

531-
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
532-
std::move(valueAddress));
531+
return OpenedExistential(std::move(typeResult),
532+
std::move(payloadAddress));
533533
}
534534

535-
OpenedExistential
535+
Result<OpenedExistential>
536536
getDynamicTypeAndAddressOpaqueExistential(RemoteAddress object) {
537537
auto result = Reader.readMetadataAndValueOpaqueExistential(object);
538538
if (!result)
539-
return getFailure<std::pair<Type, RemoteAddress>>();
540-
RemoteAddress metadataAddress = result->first;
541-
RemoteAddress valueAddress = result->second;
539+
return getFailure<OpenedExistential>();
542540

543541
auto typeResult =
544-
Reader.readTypeFromMetadata(metadataAddress.getAddressData());
542+
Reader.readTypeFromMetadata(result->MetadataAddress.getAddressData());
545543
if (!typeResult)
546-
return getFailure<std::pair<Type, RemoteAddress>>();
544+
return getFailure<OpenedExistential>();
547545

548546
// When the existential wraps a class type, LLDB expects that the
549547
// address returned is the class instance itself and not the address
550548
// of the reference.
549+
auto payloadAddress = result->PayloadAddress;
551550
if (typeResult->getClassOrBoundGenericClass()) {
552-
auto pointerval = Reader.readPointerValue(valueAddress.getAddressData());
551+
auto pointerval = Reader.readPointerValue(
552+
payloadAddress.getAddressData());
553553
if (!pointerval)
554-
return getFailure<std::pair<Type, RemoteAddress>>();
554+
return getFailure<OpenedExistential>();
555555

556-
valueAddress = RemoteAddress(*pointerval);
556+
payloadAddress = RemoteAddress(*pointerval);
557557
}
558558

559-
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
560-
std::move(valueAddress));
559+
return OpenedExistential(std::move(typeResult),
560+
std::move(payloadAddress));
561561
}
562562

563-
OpenedExistential
563+
Result<OpenedExistential>
564564
getDynamicTypeAndAddressExistentialMetatype(RemoteAddress object) {
565565
// The value of the address is just the input address.
566566
// The type is obtained through the following sequence of steps:
@@ -569,21 +569,21 @@ class RemoteASTContextConcreteImpl final : public RemoteASTContextImpl {
569569
// 3) Wrapping the resolved type in an existential metatype.
570570
auto pointerval = Reader.readPointerValue(object.getAddressData());
571571
if (!pointerval)
572-
return getFailure<std::pair<Type, RemoteAddress>>();
572+
return getFailure<OpenedExistential>();
573573
auto typeResult = Reader.readTypeFromMetadata(*pointerval);
574574
if (!typeResult)
575-
return getFailure<std::pair<Type, RemoteAddress>>();
575+
return getFailure<OpenedExistential>();
576576
auto wrappedType = ExistentialMetatypeType::get(typeResult);
577577
if (!wrappedType)
578-
return getFailure<std::pair<Type, RemoteAddress>>();
579-
return std::make_pair<Type, RemoteAddress>(std::move(wrappedType),
580-
std::move(object));
578+
return getFailure<OpenedExistential>();
579+
return OpenedExistential(std::move(wrappedType),
580+
std::move(object));
581581
}
582582

583583
/// Resolve the dynamic type and the value address of an error existential
584584
/// object, Unlike getDynamicTypeAndAddressForExistential(), this function
585585
/// takes the address of the instance and not the address of the reference.
586-
OpenedExistential
586+
Result<OpenedExistential>
587587
getDynamicTypeAndAddressForError(RemoteAddress object) override {
588588
return getDynamicTypeAndAddressErrorExistential(object,
589589
/*dereference=*/false);
@@ -593,12 +593,12 @@ class RemoteASTContextConcreteImpl final : public RemoteASTContextImpl {
593593
/// given its address and its static type. For class and error existentials,
594594
/// this API takes a pointer to the instance reference rather than the
595595
/// instance reference itself.
596-
OpenedExistential
596+
Result<OpenedExistential>
597597
getDynamicTypeAndAddressForExistential(RemoteAddress object,
598598
Type staticType) override {
599599
// If this is not an existential, give up.
600600
if (!staticType->isAnyExistentialType())
601-
return getFailure<std::pair<Type, RemoteAddress>>();
601+
return getFailure<OpenedExistential>();
602602

603603
// Handle the case where this is an ExistentialMetatype.
604604
if (!staticType->isExistentialType())
@@ -674,13 +674,13 @@ RemoteASTContext::getHeapMetadataForObject(remote::RemoteAddress address) {
674674
return asImpl(Impl)->getHeapMetadataForObject(address);
675675
}
676676

677-
OpenedExistential
677+
Result<OpenedExistential>
678678
RemoteASTContext::getDynamicTypeAndAddressForError(
679679
remote::RemoteAddress address) {
680680
return asImpl(Impl)->getDynamicTypeAndAddressForError(address);
681681
}
682682

683-
OpenedExistential
683+
Result<OpenedExistential>
684684
RemoteASTContext::getDynamicTypeAndAddressForExistential(
685685
remote::RemoteAddress address, Type staticType) {
686686
return asImpl(Impl)->getDynamicTypeAndAddressForExistential(address,

0 commit comments

Comments
 (0)