Skip to content
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
81 changes: 59 additions & 22 deletions include/swift/Runtime/GenericMetadataBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,11 @@ class GenericMetadataBuilder {
patternPointers->resolvePointer(&patternPointers->ptr[i]);
if (!patternPointer)
return *patternPointer.getError();
data.writePointer(
auto writeResult = data.writePointer(
&metadataExtraData[i + extraDataPattern->OffsetInWords],
patternPointer->template cast<const StoredPointer>());
if (!writeResult)
return *writeResult.getError();
}
}

Expand All @@ -310,7 +312,10 @@ class GenericMetadataBuilder {
if (!valueWitnesses)
return *valueWitnesses.getError();
METADATA_BUILDER_LOG("Setting initial value witnesses");
data.writePointer(&fullMetadata->ValueWitnesses, *valueWitnesses);
auto writeResult =
data.writePointer(&fullMetadata->ValueWitnesses, *valueWitnesses);
if (!writeResult)
return *writeResult.getError();

// Set the metadata kind.
METADATA_BUILDER_LOG("Setting metadata kind %#x",
Expand All @@ -319,7 +324,9 @@ class GenericMetadataBuilder {

// Set the type descriptor.
METADATA_BUILDER_LOG("Setting descriptor");
data.writePointer(&metadata->Description, descriptionBuffer);
writeResult = data.writePointer(&metadata->Description, descriptionBuffer);
if (!writeResult)
return *writeResult.getError();

return {{}};
}
Expand Down Expand Up @@ -353,8 +360,11 @@ class GenericMetadataBuilder {
header.NumKeyArguments,
getGenericArgumentOffset(
descriptionBuffer.template cast<const TypeContextDescriptor>()));
for (unsigned i = 0; i < header.NumKeyArguments; i++)
data.writePointer(&dst[i], arguments[i]);
for (unsigned i = 0; i < header.NumKeyArguments; i++) {
auto writeResult = data.writePointer(&dst[i], arguments[i]);
if (!writeResult)
return *writeResult.getError();
}

// TODO: parameter pack support.

Expand Down Expand Up @@ -495,7 +505,11 @@ class GenericMetadataBuilder {
auto LOWER_ID##_Buffer = from.resolveFunctionPointer(&from.ptr->LOWER_ID); \
if (!LOWER_ID##_Buffer) \
return *LOWER_ID##_Buffer.getError(); \
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->LOWER_ID, *LOWER_ID##_Buffer);
if (auto *error = vwtBuffer \
.writeFunctionPointer(&vwtBuffer.ptr->LOWER_ID, \
*LOWER_ID##_Buffer) \
.getError()) \
return *error;
#define DATA_VALUE_WITNESS(LOWER_ID, UPPER_ID, TYPE)
#include "swift/ABI/ValueWitness.def"

Expand All @@ -520,40 +534,56 @@ class GenericMetadataBuilder {
(size_t)flags.getAlignmentMask());
switch (sizeWithAlignmentMask(layout.size, flags.getAlignmentMask(),
hasExtraInhabitants)) {
default:
default: {
// For uncommon layouts, use value witnesses that work with an arbitrary
// size and alignment.
METADATA_BUILDER_LOG("Uncommon layout case, flags.isInlineStorage=%s",
flags.isInlineStorage() ? "true" : "false");
if (flags.isInlineStorage()) {
if (!pod_direct_initializeBufferWithCopyOfBuffer)
return *pod_direct_initializeBufferWithCopyOfBuffer.getError();
vwtBuffer.writeFunctionPointer(
auto writeResult = vwtBuffer.writeFunctionPointer(
&vwtBuffer.ptr->initializeBufferWithCopyOfBuffer,
*pod_direct_initializeBufferWithCopyOfBuffer);
if (!writeResult)
return *writeResult.getError();
} else {
if (!pod_indirect_initializeBufferWithCopyOfBuffer)
return *pod_indirect_initializeBufferWithCopyOfBuffer.getError();
vwtBuffer.writeFunctionPointer(
auto writeResult = vwtBuffer.writeFunctionPointer(
&vwtBuffer.ptr->initializeBufferWithCopyOfBuffer,
*pod_indirect_initializeBufferWithCopyOfBuffer);
if (!writeResult)
return *writeResult.getError();
}
if (!pod_destroy)
return *pod_destroy.getError();
if (!pod_copy)
return *pod_copy.getError();
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->destroy, *pod_destroy);
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->initializeWithCopy,
*pod_copy);
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->initializeWithTake,
*pod_copy);
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->assignWithCopy,
*pod_copy);
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->assignWithTake,
*pod_copy);
auto writeResult = vwtBuffer.writeFunctionPointer(
&vwtBuffer.ptr->destroy, *pod_destroy);
if (!writeResult)
return *writeResult.getError();
writeResult = vwtBuffer.writeFunctionPointer(
&vwtBuffer.ptr->initializeWithCopy, *pod_copy);
if (!writeResult)
return *writeResult.getError();
writeResult = vwtBuffer.writeFunctionPointer(
&vwtBuffer.ptr->initializeWithTake, *pod_copy);
if (!writeResult)
return *writeResult.getError();
writeResult = vwtBuffer.writeFunctionPointer(
&vwtBuffer.ptr->assignWithCopy, *pod_copy);
if (!writeResult)
return *writeResult.getError();
writeResult = vwtBuffer.writeFunctionPointer(
&vwtBuffer.ptr->assignWithTake, *pod_copy);
if (!writeResult)
return *writeResult.getError();
// getEnumTagSinglePayload and storeEnumTagSinglePayload are not
// interestingly optimizable based on POD-ness.
return {{}};
}

case sizeWithAlignmentMask(1, 0, 0): {
METADATA_BUILDER_LOG("case sizeWithAlignmentMask(1, 0, 0)");
Expand Down Expand Up @@ -629,8 +659,10 @@ class GenericMetadataBuilder {
// Use POD value witnesses for operations that do an initializeWithTake.
if (!pod_copy)
return *pod_copy.getError();
vwtBuffer.writeFunctionPointer(&vwtBuffer.ptr->initializeWithTake,
*pod_copy);
auto writeResult = vwtBuffer.writeFunctionPointer(
&vwtBuffer.ptr->initializeWithTake, *pod_copy);
if (!writeResult)
return *writeResult.getError();
}
return {{}};
}
Expand Down Expand Up @@ -761,7 +793,10 @@ class GenericMetadataBuilder {
auto fptr = oldVWTBuffer->resolveFunctionPointer(&oldVWT->LOWER_ID); \
if (!fptr) \
return *fptr.getError(); \
newVWTData.writeFunctionPointer(&newVWT->LOWER_ID, *fptr); \
if (auto *error = \
newVWTData.writeFunctionPointer(&newVWT->LOWER_ID, *fptr) \
.getError()) \
return *error; \
}
#include "swift/ABI/ValueWitness.def"

Expand All @@ -774,9 +809,11 @@ class GenericMetadataBuilder {
newVWT->extraInhabitantCount = layout.extraInhabitantCount;
newVWT->flags = layout.flags;

metadataBuffer.writePointer(
auto writeResult = metadataBuffer.writePointer(
&metadataBuffer.ptr->ValueWitnesses,
newVWTData.template cast<const ValueWitnessTable>());
if (!writeResult)
return *writeResult.getError();
return {{}}; // success
}

Expand Down
Loading