Add initRawStructMetadata2 for safety

This commit is contained in:
Alejandro Alonso
2024-08-20 10:26:38 -07:00
parent 9faf615c88
commit f2f82a7de6
7 changed files with 122 additions and 22 deletions

View File

@@ -587,10 +587,10 @@ protected:
SWIFT_INLINE_BITFIELD_EMPTY(TypeDecl, ValueDecl);
SWIFT_INLINE_BITFIELD_FULL(GenericTypeParamDecl, TypeDecl, 16+16+8+1,
SWIFT_INLINE_BITFIELD_FULL(GenericTypeParamDecl, TypeDecl, 16+16+3+1,
Depth : 16,
Index : 16,
ParamKind : 8,
ParamKind : 3,
/// Whether this generic parameter represents an opaque type.
IsOpaqueType : 1

View File

@@ -79,6 +79,7 @@ FEATURE(Differentiation, FUTURE)
FEATURE(ClearSensitive, FUTURE)
FEATURE(UpdatePureObjCClassMetadata, FUTURE)
FEATURE(ValueGenericType, FUTURE)
FEATURE(InitRawStructMetadata2, FUTURE)
#undef FEATURE
#undef FUTURE

View File

@@ -1057,6 +1057,14 @@ void _swift_registerConcurrencyStandardTypeDescriptors(
/// as the basis for the layout.
SWIFT_RUNTIME_EXPORT
void swift_initRawStructMetadata(StructMetadata *self,
StructLayoutFlags flags,
const TypeLayout *likeType,
ssize_t count);
/// Initialize the value witness table for a struct using the provided like type
/// as the basis for the layout.
SWIFT_RUNTIME_EXPORT
void swift_initRawStructMetadata2(StructMetadata *self,
StructLayoutFlags structLayoutFlags,
const TypeLayout *likeType,
intptr_t count,

View File

@@ -2823,13 +2823,26 @@ FUNCTION(GenericInstantiateLayoutString,
UNKNOWN_MEMEFFECTS)
// void swift_initRawStructMetadata(Metadata *structType,
// StructLayoutFlags flags,
// const TypeLayout *likeType,
// int32_t count);
FUNCTION(InitRawStructMetadata,
swift_initRawStructMetadata,
C_CC, InitRawStructMetadataAvailability,
RETURNS(VoidTy),
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy->getPointerTo(0), Int32Ty),
ATTRS(NoUnwind),
EFFECT(MetaData),
UNKNOWN_MEMEFFECTS)
// void swift_initRawStructMetadata2(Metadata *structType,
// StructLayoutFlags structLayoutFlags,
// const TypeLayout *likeType,
// intptr_t count,
// RawLayoutFlags rawLayoutFlags);
FUNCTION(InitRawStructMetadata,
swift_initRawStructMetadata,
C_CC, AlwaysAvailable,
FUNCTION(InitRawStructMetadata2,
swift_initRawStructMetadata2,
C_CC, InitRawStructMetadata2Availability,
RETURNS(VoidTy),
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy->getPointerTo(0), SizeTy,
SizeTy),

View File

@@ -3213,7 +3213,7 @@ static void emitInitializeFieldOffsetVectorWithLayoutString(
IGM.getPointerSize() * numFields);
}
static void emitInitializeRawLayoutOld(IRGenFunction &IGF, SILType likeType,
static void emitInitializeRawLayoutOldOld(IRGenFunction &IGF, SILType likeType,
llvm::Value *count, SILType T,
llvm::Value *metadata,
MetadataDependencyCollector *collector) {
@@ -3296,11 +3296,11 @@ static void emitInitializeRawLayoutOld(IRGenFunction &IGF, SILType likeType,
IGF.Builder.CreateLifetimeEnd(fieldLayouts, IGM.getPointerSize());
}
static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
static void emitInitializeRawLayoutOld(IRGenFunction &IGF, SILType likeType,
llvm::Value *count, SILType T,
llvm::Value *metadata,
MetadataDependencyCollector *collector) {
// If our deployment target doesn't contain the new swift_initRawStructMetadata,
// If our deployment target doesn't contain the swift_initRawStructMetadata,
// emit a call to the swift_initStructMetadata tricking it into thinking
// we have a single field.
auto deploymentAvailability =
@@ -3310,6 +3310,39 @@ static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
if (!IGF.IGM.Context.LangOpts.DisableAvailabilityChecking &&
!deploymentAvailability.isContainedIn(initRawAvail) &&
!IGF.IGM.getSwiftModule()->isStdlibModule()) {
emitInitializeRawLayoutOldOld(IGF, likeType, count, T, metadata, collector);
return;
}
auto &IGM = IGF.IGM;
auto likeTypeLayout = emitTypeLayoutRef(IGF, likeType, collector);
StructLayoutFlags flags = StructLayoutFlags::Swift5Algorithm;
// If we don't have a count, then we're the 'like:' variant and we need to
// pass '-1' to the runtime call.
if (!count) {
count = llvm::ConstantInt::get(IGF.IGM.Int32Ty, -1);
}
// Call swift_initRawStructMetadata().
IGF.Builder.CreateCall(IGM.getInitRawStructMetadataFunctionPointer(),
{metadata, IGM.getSize(Size(uintptr_t(flags))),
likeTypeLayout, count});
}
static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
llvm::Value *count, SILType T,
llvm::Value *metadata,
MetadataDependencyCollector *collector) {
// If our deployment target doesn't contain the swift_initRawStructMetadata2,
// emit a call to the older swift_initRawStructMetadata.
auto deploymentAvailability =
AvailabilityContext::forDeploymentTarget(IGF.IGM.Context);
auto initRaw2Avail = IGF.IGM.Context.getInitRawStructMetadata2Availability();
if (!IGF.IGM.Context.LangOpts.DisableAvailabilityChecking &&
!deploymentAvailability.isContainedIn(initRaw2Avail) &&
!IGF.IGM.getSwiftModule()->isStdlibModule()) {
emitInitializeRawLayoutOld(IGF, likeType, count, T, metadata, collector);
return;
}
@@ -3331,8 +3364,8 @@ static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
rawLayoutFlags |= RawLayoutFlags::IsArray;
}
// Call swift_initRawStructMetadata().
IGF.Builder.CreateCall(IGM.getInitRawStructMetadataFunctionPointer(),
// Call swift_initRawStructMetadata2().
IGF.Builder.CreateCall(IGM.getInitRawStructMetadata2FunctionPointer(),
{metadata,
IGM.getSize(Size(uintptr_t(structLayoutflags))),
likeTypeLayout,

View File

@@ -986,6 +986,22 @@ namespace RuntimeConstants {
return RuntimeAvailability::AlwaysAvailable;
}
RuntimeAvailability InitRawStructMetadataAvailability(ASTContext &Context) {
auto featureAvailability = Context.getInitRawStructMetadataAvailability();
if (!isDeploymentAvailabilityContainedIn(Context, featureAvailability)) {
return RuntimeAvailability::ConditionallyAvailable;
}
return RuntimeAvailability::AlwaysAvailable;
}
RuntimeAvailability InitRawStructMetadata2Availability(ASTContext &Context) {
auto featureAvailability = Context.getInitRawStructMetadata2Availability();
if (!isDeploymentAvailabilityContainedIn(Context, featureAvailability)) {
return RuntimeAvailability::ConditionallyAvailable;
}
return RuntimeAvailability::AlwaysAvailable;
}
} // namespace RuntimeConstants
// We don't use enough attributes to justify generalizing the

View File

@@ -3028,6 +3028,35 @@ metadata:
/// Initialize the value witness table for a @_rawLayout struct.
SWIFT_RUNTIME_EXPORT
void swift::swift_initRawStructMetadata(StructMetadata *structType,
StructLayoutFlags layoutFlags,
const TypeLayout *likeTypeLayout,
ssize_t count) {
auto vwtable = getMutableVWTableForInit(structType, layoutFlags);
// The existing vwt function entries are all fine to preserve, the only thing
// we need to initialize is the actual type layout.
auto size = likeTypeLayout->size;
auto stride = likeTypeLayout->stride;
auto alignMask = likeTypeLayout->flags.getAlignmentMask();
auto extraInhabitantCount = likeTypeLayout->extraInhabitantCount;
// If our count is not -1, we're dealing an array like layout.
if (count != -1) {
stride *= (size_t)count;
size = stride;
}
vwtable->size = size;
vwtable->stride = stride;
vwtable->flags = ValueWitnessFlags()
.withAlignmentMask(alignMask)
.withCopyable(false);
vwtable->extraInhabitantCount = extraInhabitantCount;
}
/// Initialize the value witness table for a @_rawLayout struct.
SWIFT_RUNTIME_EXPORT
void swift::swift_initRawStructMetadata2(StructMetadata *structType,
StructLayoutFlags structLayoutFlags,
const TypeLayout *likeTypeLayout,
intptr_t count,