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_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,
|
Depth : 16,
|
||||||
Index : 16,
|
Index : 16,
|
||||||
ParamKind : 8,
|
ParamKind : 3,
|
||||||
|
|
||||||
/// Whether this generic parameter represents an opaque type.
|
/// Whether this generic parameter represents an opaque type.
|
||||||
IsOpaqueType : 1
|
IsOpaqueType : 1
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ FEATURE(Differentiation, FUTURE)
|
|||||||
FEATURE(ClearSensitive, FUTURE)
|
FEATURE(ClearSensitive, FUTURE)
|
||||||
FEATURE(UpdatePureObjCClassMetadata, FUTURE)
|
FEATURE(UpdatePureObjCClassMetadata, FUTURE)
|
||||||
FEATURE(ValueGenericType, FUTURE)
|
FEATURE(ValueGenericType, FUTURE)
|
||||||
|
FEATURE(InitRawStructMetadata2, FUTURE)
|
||||||
|
|
||||||
#undef FEATURE
|
#undef FEATURE
|
||||||
#undef FUTURE
|
#undef FUTURE
|
||||||
|
|||||||
@@ -1057,6 +1057,14 @@ void _swift_registerConcurrencyStandardTypeDescriptors(
|
|||||||
/// as the basis for the layout.
|
/// as the basis for the layout.
|
||||||
SWIFT_RUNTIME_EXPORT
|
SWIFT_RUNTIME_EXPORT
|
||||||
void swift_initRawStructMetadata(StructMetadata *self,
|
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,
|
StructLayoutFlags structLayoutFlags,
|
||||||
const TypeLayout *likeType,
|
const TypeLayout *likeType,
|
||||||
intptr_t count,
|
intptr_t count,
|
||||||
|
|||||||
@@ -2823,13 +2823,26 @@ FUNCTION(GenericInstantiateLayoutString,
|
|||||||
UNKNOWN_MEMEFFECTS)
|
UNKNOWN_MEMEFFECTS)
|
||||||
|
|
||||||
// void swift_initRawStructMetadata(Metadata *structType,
|
// 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,
|
// StructLayoutFlags structLayoutFlags,
|
||||||
// const TypeLayout *likeType,
|
// const TypeLayout *likeType,
|
||||||
// intptr_t count,
|
// intptr_t count,
|
||||||
// RawLayoutFlags rawLayoutFlags);
|
// RawLayoutFlags rawLayoutFlags);
|
||||||
FUNCTION(InitRawStructMetadata,
|
FUNCTION(InitRawStructMetadata2,
|
||||||
swift_initRawStructMetadata,
|
swift_initRawStructMetadata2,
|
||||||
C_CC, AlwaysAvailable,
|
C_CC, InitRawStructMetadata2Availability,
|
||||||
RETURNS(VoidTy),
|
RETURNS(VoidTy),
|
||||||
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy->getPointerTo(0), SizeTy,
|
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy->getPointerTo(0), SizeTy,
|
||||||
SizeTy),
|
SizeTy),
|
||||||
|
|||||||
@@ -3213,7 +3213,7 @@ static void emitInitializeFieldOffsetVectorWithLayoutString(
|
|||||||
IGM.getPointerSize() * numFields);
|
IGM.getPointerSize() * numFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emitInitializeRawLayoutOld(IRGenFunction &IGF, SILType likeType,
|
static void emitInitializeRawLayoutOldOld(IRGenFunction &IGF, SILType likeType,
|
||||||
llvm::Value *count, SILType T,
|
llvm::Value *count, SILType T,
|
||||||
llvm::Value *metadata,
|
llvm::Value *metadata,
|
||||||
MetadataDependencyCollector *collector) {
|
MetadataDependencyCollector *collector) {
|
||||||
@@ -3296,11 +3296,11 @@ static void emitInitializeRawLayoutOld(IRGenFunction &IGF, SILType likeType,
|
|||||||
IGF.Builder.CreateLifetimeEnd(fieldLayouts, IGM.getPointerSize());
|
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 *count, SILType T,
|
||||||
llvm::Value *metadata,
|
llvm::Value *metadata,
|
||||||
MetadataDependencyCollector *collector) {
|
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
|
// emit a call to the swift_initStructMetadata tricking it into thinking
|
||||||
// we have a single field.
|
// we have a single field.
|
||||||
auto deploymentAvailability =
|
auto deploymentAvailability =
|
||||||
@@ -3310,6 +3310,39 @@ static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
|
|||||||
if (!IGF.IGM.Context.LangOpts.DisableAvailabilityChecking &&
|
if (!IGF.IGM.Context.LangOpts.DisableAvailabilityChecking &&
|
||||||
!deploymentAvailability.isContainedIn(initRawAvail) &&
|
!deploymentAvailability.isContainedIn(initRawAvail) &&
|
||||||
!IGF.IGM.getSwiftModule()->isStdlibModule()) {
|
!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);
|
emitInitializeRawLayoutOld(IGF, likeType, count, T, metadata, collector);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3331,8 +3364,8 @@ static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
|
|||||||
rawLayoutFlags |= RawLayoutFlags::IsArray;
|
rawLayoutFlags |= RawLayoutFlags::IsArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call swift_initRawStructMetadata().
|
// Call swift_initRawStructMetadata2().
|
||||||
IGF.Builder.CreateCall(IGM.getInitRawStructMetadataFunctionPointer(),
|
IGF.Builder.CreateCall(IGM.getInitRawStructMetadata2FunctionPointer(),
|
||||||
{metadata,
|
{metadata,
|
||||||
IGM.getSize(Size(uintptr_t(structLayoutflags))),
|
IGM.getSize(Size(uintptr_t(structLayoutflags))),
|
||||||
likeTypeLayout,
|
likeTypeLayout,
|
||||||
|
|||||||
@@ -986,6 +986,22 @@ namespace RuntimeConstants {
|
|||||||
return RuntimeAvailability::AlwaysAvailable;
|
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
|
} // namespace RuntimeConstants
|
||||||
|
|
||||||
// We don't use enough attributes to justify generalizing the
|
// We don't use enough attributes to justify generalizing the
|
||||||
|
|||||||
@@ -3028,6 +3028,35 @@ metadata:
|
|||||||
/// Initialize the value witness table for a @_rawLayout struct.
|
/// Initialize the value witness table for a @_rawLayout struct.
|
||||||
SWIFT_RUNTIME_EXPORT
|
SWIFT_RUNTIME_EXPORT
|
||||||
void swift::swift_initRawStructMetadata(StructMetadata *structType,
|
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,
|
StructLayoutFlags structLayoutFlags,
|
||||||
const TypeLayout *likeTypeLayout,
|
const TypeLayout *likeTypeLayout,
|
||||||
intptr_t count,
|
intptr_t count,
|
||||||
|
|||||||
Reference in New Issue
Block a user