mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Add initRawStructMetadata2 for safety
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -79,6 +79,7 @@ FEATURE(Differentiation, FUTURE)
|
||||
FEATURE(ClearSensitive, FUTURE)
|
||||
FEATURE(UpdatePureObjCClassMetadata, FUTURE)
|
||||
FEATURE(ValueGenericType, FUTURE)
|
||||
FEATURE(InitRawStructMetadata2, FUTURE)
|
||||
|
||||
#undef FEATURE
|
||||
#undef FUTURE
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user