Skip to content

Commit 7092262

Browse files
committed
Runtime: Allow taking out of inline opaque existentials
Only values stored in the outline boxed existential representation can be shared.
1 parent 383b0ab commit 7092262

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

stdlib/public/runtime/Casting.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,10 @@ static void unwrapExistential(OpaqueValue *src,
15931593
auto opaqueContainer = reinterpret_cast<OpaqueExistentialContainer*>(src);
15941594
srcCapturedType = opaqueContainer->Type;
15951595
srcValue = srcType->projectValue(src);
1596-
canTake = false;
1596+
// Can't take out of possibly shared existential boxes.
1597+
canTake = (src == srcValue);
1598+
assert(canTake == srcCapturedType->getValueWitnesses()->isValueInline() &&
1599+
"Only inline storage is take-able");
15971600
#else
15981601
auto opaqueContainer = reinterpret_cast<OpaqueExistentialContainer*>(src);
15991602
srcCapturedType = opaqueContainer->Type;
@@ -1653,9 +1656,7 @@ static bool _dynamicCastFromExistential(OpaqueValue *dest,
16531656
} else {
16541657
#ifdef SWIFT_RUNTIME_ENABLE_COW_EXISTENTIALS
16551658
assert(!isOutOfLine &&
1656-
srcType->getRepresentation() !=
1657-
ExistentialTypeRepresentation::Opaque &&
1658-
"Should only see inline represenations and no opaque existential");
1659+
"Should only see inline represenations of existentials");
16591660
#else
16601661
// swift_dynamicCast took or destroyed the value as per the original request
16611662
// We may still have an opaque existential container to deallocate.

stdlib/public/runtime/Metadata.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2228,8 +2228,13 @@ ExistentialTypeMetadata::mayTakeValue(const OpaqueValue *container) const {
22282228
// Opaque existential containers uniquely own their contained value.
22292229
case ExistentialTypeRepresentation::Opaque:
22302230
#ifdef SWIFT_RUNTIME_ENABLE_COW_EXISTENTIALS
2231+
{
22312232
// We can't take from a shared existential box without checking uniqueness.
2232-
return false;
2233+
auto *opaque =
2234+
reinterpret_cast<const OpaqueExistentialContainer *>(container);
2235+
auto *vwt = opaque->Type->getValueWitnesses();
2236+
return vwt->isValueInline();
2237+
}
22332238
#else
22342239
return true;
22352240
#endif

0 commit comments

Comments
 (0)