Skip to content

Commit f2f82a7

Browse files
committed
Add initRawStructMetadata2 for safety
1 parent 9faf615 commit f2f82a7

File tree

7 files changed

+122
-22
lines changed

7 files changed

+122
-22
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,10 +587,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
587587

588588
SWIFT_INLINE_BITFIELD_EMPTY(TypeDecl, ValueDecl);
589589

590-
SWIFT_INLINE_BITFIELD_FULL(GenericTypeParamDecl, TypeDecl, 16+16+8+1,
590+
SWIFT_INLINE_BITFIELD_FULL(GenericTypeParamDecl, TypeDecl, 16+16+3+1,
591591
Depth : 16,
592592
Index : 16,
593-
ParamKind : 8,
593+
ParamKind : 3,
594594

595595
/// Whether this generic parameter represents an opaque type.
596596
IsOpaqueType : 1

include/swift/AST/FeatureAvailability.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ FEATURE(Differentiation, FUTURE)
7979
FEATURE(ClearSensitive, FUTURE)
8080
FEATURE(UpdatePureObjCClassMetadata, FUTURE)
8181
FEATURE(ValueGenericType, FUTURE)
82+
FEATURE(InitRawStructMetadata2, FUTURE)
8283

8384
#undef FEATURE
8485
#undef FUTURE

include/swift/Runtime/Metadata.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,10 +1057,18 @@ void _swift_registerConcurrencyStandardTypeDescriptors(
10571057
/// as the basis for the layout.
10581058
SWIFT_RUNTIME_EXPORT
10591059
void swift_initRawStructMetadata(StructMetadata *self,
1060-
StructLayoutFlags structLayoutFlags,
1060+
StructLayoutFlags flags,
10611061
const TypeLayout *likeType,
1062-
intptr_t count,
1063-
RawLayoutFlags rawLayoutFlags);
1062+
ssize_t count);
1063+
1064+
/// Initialize the value witness table for a struct using the provided like type
1065+
/// as the basis for the layout.
1066+
SWIFT_RUNTIME_EXPORT
1067+
void swift_initRawStructMetadata2(StructMetadata *self,
1068+
StructLayoutFlags structLayoutFlags,
1069+
const TypeLayout *likeType,
1070+
intptr_t count,
1071+
RawLayoutFlags rawLayoutFlags);
10641072

10651073
/// Check if the given generic arguments are valid inputs for the generic type
10661074
/// context and if so call the metadata access function and return the metadata.

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,13 +2823,26 @@ FUNCTION(GenericInstantiateLayoutString,
28232823
UNKNOWN_MEMEFFECTS)
28242824

28252825
// void swift_initRawStructMetadata(Metadata *structType,
2826-
// StructLayoutFlags structLayoutFlags,
2826+
// StructLayoutFlags flags,
28272827
// const TypeLayout *likeType,
2828-
// intptr_t count,
2829-
// RawLayoutFlags rawLayoutFlags);
2828+
// int32_t count);
28302829
FUNCTION(InitRawStructMetadata,
28312830
swift_initRawStructMetadata,
2832-
C_CC, AlwaysAvailable,
2831+
C_CC, InitRawStructMetadataAvailability,
2832+
RETURNS(VoidTy),
2833+
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy->getPointerTo(0), Int32Ty),
2834+
ATTRS(NoUnwind),
2835+
EFFECT(MetaData),
2836+
UNKNOWN_MEMEFFECTS)
2837+
2838+
// void swift_initRawStructMetadata2(Metadata *structType,
2839+
// StructLayoutFlags structLayoutFlags,
2840+
// const TypeLayout *likeType,
2841+
// intptr_t count,
2842+
// RawLayoutFlags rawLayoutFlags);
2843+
FUNCTION(InitRawStructMetadata2,
2844+
swift_initRawStructMetadata2,
2845+
C_CC, InitRawStructMetadata2Availability,
28332846
RETURNS(VoidTy),
28342847
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy->getPointerTo(0), SizeTy,
28352848
SizeTy),

lib/IRGen/GenMeta.cpp

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3213,9 +3213,9 @@ static void emitInitializeFieldOffsetVectorWithLayoutString(
32133213
IGM.getPointerSize() * numFields);
32143214
}
32153215

3216-
static void emitInitializeRawLayoutOld(IRGenFunction &IGF, SILType likeType,
3217-
llvm::Value *count, SILType T,
3218-
llvm::Value *metadata,
3216+
static void emitInitializeRawLayoutOldOld(IRGenFunction &IGF, SILType likeType,
3217+
llvm::Value *count, SILType T,
3218+
llvm::Value *metadata,
32193219
MetadataDependencyCollector *collector) {
32203220
auto &IGM = IGF.IGM;
32213221

@@ -3296,11 +3296,11 @@ static void emitInitializeRawLayoutOld(IRGenFunction &IGF, SILType likeType,
32963296
IGF.Builder.CreateLifetimeEnd(fieldLayouts, IGM.getPointerSize());
32973297
}
32983298

3299-
static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
3300-
llvm::Value *count, SILType T,
3301-
llvm::Value *metadata,
3302-
MetadataDependencyCollector *collector) {
3303-
// If our deployment target doesn't contain the new swift_initRawStructMetadata,
3299+
static void emitInitializeRawLayoutOld(IRGenFunction &IGF, SILType likeType,
3300+
llvm::Value *count, SILType T,
3301+
llvm::Value *metadata,
3302+
MetadataDependencyCollector *collector) {
3303+
// If our deployment target doesn't contain the swift_initRawStructMetadata,
33043304
// emit a call to the swift_initStructMetadata tricking it into thinking
33053305
// we have a single field.
33063306
auto deploymentAvailability =
@@ -3310,6 +3310,39 @@ static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
33103310
if (!IGF.IGM.Context.LangOpts.DisableAvailabilityChecking &&
33113311
!deploymentAvailability.isContainedIn(initRawAvail) &&
33123312
!IGF.IGM.getSwiftModule()->isStdlibModule()) {
3313+
emitInitializeRawLayoutOldOld(IGF, likeType, count, T, metadata, collector);
3314+
return;
3315+
}
3316+
3317+
auto &IGM = IGF.IGM;
3318+
auto likeTypeLayout = emitTypeLayoutRef(IGF, likeType, collector);
3319+
StructLayoutFlags flags = StructLayoutFlags::Swift5Algorithm;
3320+
3321+
// If we don't have a count, then we're the 'like:' variant and we need to
3322+
// pass '-1' to the runtime call.
3323+
if (!count) {
3324+
count = llvm::ConstantInt::get(IGF.IGM.Int32Ty, -1);
3325+
}
3326+
3327+
// Call swift_initRawStructMetadata().
3328+
IGF.Builder.CreateCall(IGM.getInitRawStructMetadataFunctionPointer(),
3329+
{metadata, IGM.getSize(Size(uintptr_t(flags))),
3330+
likeTypeLayout, count});
3331+
}
3332+
3333+
static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
3334+
llvm::Value *count, SILType T,
3335+
llvm::Value *metadata,
3336+
MetadataDependencyCollector *collector) {
3337+
// If our deployment target doesn't contain the swift_initRawStructMetadata2,
3338+
// emit a call to the older swift_initRawStructMetadata.
3339+
auto deploymentAvailability =
3340+
AvailabilityContext::forDeploymentTarget(IGF.IGM.Context);
3341+
auto initRaw2Avail = IGF.IGM.Context.getInitRawStructMetadata2Availability();
3342+
3343+
if (!IGF.IGM.Context.LangOpts.DisableAvailabilityChecking &&
3344+
!deploymentAvailability.isContainedIn(initRaw2Avail) &&
3345+
!IGF.IGM.getSwiftModule()->isStdlibModule()) {
33133346
emitInitializeRawLayoutOld(IGF, likeType, count, T, metadata, collector);
33143347
return;
33153348
}
@@ -3331,8 +3364,8 @@ static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
33313364
rawLayoutFlags |= RawLayoutFlags::IsArray;
33323365
}
33333366

3334-
// Call swift_initRawStructMetadata().
3335-
IGF.Builder.CreateCall(IGM.getInitRawStructMetadataFunctionPointer(),
3367+
// Call swift_initRawStructMetadata2().
3368+
IGF.Builder.CreateCall(IGM.getInitRawStructMetadata2FunctionPointer(),
33363369
{metadata,
33373370
IGM.getSize(Size(uintptr_t(structLayoutflags))),
33383371
likeTypeLayout,

lib/IRGen/IRGenModule.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,22 @@ namespace RuntimeConstants {
986986
return RuntimeAvailability::AlwaysAvailable;
987987
}
988988

989+
RuntimeAvailability InitRawStructMetadataAvailability(ASTContext &Context) {
990+
auto featureAvailability = Context.getInitRawStructMetadataAvailability();
991+
if (!isDeploymentAvailabilityContainedIn(Context, featureAvailability)) {
992+
return RuntimeAvailability::ConditionallyAvailable;
993+
}
994+
return RuntimeAvailability::AlwaysAvailable;
995+
}
996+
997+
RuntimeAvailability InitRawStructMetadata2Availability(ASTContext &Context) {
998+
auto featureAvailability = Context.getInitRawStructMetadata2Availability();
999+
if (!isDeploymentAvailabilityContainedIn(Context, featureAvailability)) {
1000+
return RuntimeAvailability::ConditionallyAvailable;
1001+
}
1002+
return RuntimeAvailability::AlwaysAvailable;
1003+
}
1004+
9891005
} // namespace RuntimeConstants
9901006

9911007
// We don't use enough attributes to justify generalizing the

stdlib/public/runtime/Metadata.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3028,10 +3028,39 @@ void swift::_swift_addRefCountStringForMetatype(LayoutStringWriter &writer,
30283028
/// Initialize the value witness table for a @_rawLayout struct.
30293029
SWIFT_RUNTIME_EXPORT
30303030
void swift::swift_initRawStructMetadata(StructMetadata *structType,
3031-
StructLayoutFlags structLayoutFlags,
3031+
StructLayoutFlags layoutFlags,
30323032
const TypeLayout *likeTypeLayout,
3033-
intptr_t count,
3034-
RawLayoutFlags rawLayoutFlags) {
3033+
ssize_t count) {
3034+
auto vwtable = getMutableVWTableForInit(structType, layoutFlags);
3035+
3036+
// The existing vwt function entries are all fine to preserve, the only thing
3037+
// we need to initialize is the actual type layout.
3038+
auto size = likeTypeLayout->size;
3039+
auto stride = likeTypeLayout->stride;
3040+
auto alignMask = likeTypeLayout->flags.getAlignmentMask();
3041+
auto extraInhabitantCount = likeTypeLayout->extraInhabitantCount;
3042+
3043+
// If our count is not -1, we're dealing an array like layout.
3044+
if (count != -1) {
3045+
stride *= (size_t)count;
3046+
size = stride;
3047+
}
3048+
3049+
vwtable->size = size;
3050+
vwtable->stride = stride;
3051+
vwtable->flags = ValueWitnessFlags()
3052+
.withAlignmentMask(alignMask)
3053+
.withCopyable(false);
3054+
vwtable->extraInhabitantCount = extraInhabitantCount;
3055+
}
3056+
3057+
/// Initialize the value witness table for a @_rawLayout struct.
3058+
SWIFT_RUNTIME_EXPORT
3059+
void swift::swift_initRawStructMetadata2(StructMetadata *structType,
3060+
StructLayoutFlags structLayoutFlags,
3061+
const TypeLayout *likeTypeLayout,
3062+
intptr_t count,
3063+
RawLayoutFlags rawLayoutFlags) {
30353064
auto vwtable = getMutableVWTableForInit(structType, structLayoutFlags);
30363065

30373066
// The existing vwt function entries are all fine to preserve, the only thing

0 commit comments

Comments
 (0)