Skip to content

Commit 261b128

Browse files
authored
Merge pull request #21103 from jckarter/unconditional-cast-source-loc-abi-5.0
[5.0] Runtime: Provide ABI space for source location info in unconditional casts.
2 parents 449aa71 + 650ea63 commit 261b128

14 files changed

+190
-82
lines changed

include/swift/Runtime/Casting.h

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,16 @@ swift_dynamicCastClass(const void *object, const ClassMetadata *targetType);
6262
/// \param object The object to cast.
6363
/// \param targetType The type to which we are casting, which is known to be
6464
/// a Swift class type.
65+
/// \param file The source filename from which to report failure. May be null.
66+
/// \param line The source line from which to report failure.
67+
/// \param column The source column from which to report failure.
6568
///
6669
/// \returns the object.
6770
SWIFT_RUNTIME_EXPORT
6871
const void *
6972
swift_dynamicCastClassUnconditional(const void *object,
70-
const ClassMetadata *targetType);
73+
const ClassMetadata *targetType,
74+
const char *file, unsigned line, unsigned column);
7175

7276
#if SWIFT_OBJC_INTEROP
7377
/// \brief Checked Objective-C-style dynamic cast to a class type.
@@ -103,25 +107,33 @@ swift_dynamicCastForeignClass(const void *object,
103107
/// \param object The object to cast, or nil.
104108
/// \param targetType The type to which we are casting, which is known to be
105109
/// a class type, but not necessarily valid type metadata.
110+
/// \param file The source filename from which to report failure. May be null.
111+
/// \param line The source line from which to report failure.
112+
/// \param column The source column from which to report failure.
106113
///
107114
/// \returns the object.
108115
SWIFT_RUNTIME_EXPORT
109116
const void *
110117
swift_dynamicCastObjCClassUnconditional(const void *object,
111-
const ClassMetadata *targetType);
118+
const ClassMetadata *targetType,
119+
const char *file, unsigned line, unsigned column);
112120

113121
/// \brief Unconditional, checked dynamic cast to a foreign class type.
114122
///
115123
/// \param object The object to cast, or nil.
116124
/// \param targetType The type to which we are casting, which is known to be
117125
/// a foreign class type.
126+
/// \param file The source filename from which to report failure. May be null.
127+
/// \param line The source line from which to report failure.
128+
/// \param column The source column from which to report failure.
118129
///
119130
/// \returns the object if the cast succeeds, or null otherwise.
120131
SWIFT_RUNTIME_EXPORT
121132
const void *
122133
swift_dynamicCastForeignClassUnconditional(
123134
const void *object,
124-
const ForeignClassMetadata *targetType);
135+
const ForeignClassMetadata *targetType,
136+
const char *file, unsigned line, unsigned column);
125137
#endif
126138

127139
/// \brief Checked dynamic cast of a class instance pointer to the given type.
@@ -146,11 +158,16 @@ swift_dynamicCastUnknownClass(const void *object, const Metadata *targetType);
146158
/// \param targetType The type to which we are casting, which may be either a
147159
/// class type or a wrapped Objective-C class type.
148160
///
161+
/// \param file The source filename from which to report failure. May be null.
162+
/// \param line The source line from which to report failure.
163+
/// \param column The source column from which to report failure.
164+
///
149165
/// \returns the object.
150166
SWIFT_RUNTIME_EXPORT
151167
const void *
152168
swift_dynamicCastUnknownClassUnconditional(const void *object,
153-
const Metadata *targetType);
169+
const Metadata *targetType,
170+
const char *file, unsigned line, unsigned column);
154171

155172
SWIFT_RUNTIME_EXPORT
156173
const Metadata *
@@ -159,7 +176,8 @@ swift_dynamicCastMetatype(const Metadata *sourceType,
159176
SWIFT_RUNTIME_EXPORT
160177
const Metadata *
161178
swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType,
162-
const Metadata *targetType);
179+
const Metadata *targetType,
180+
const char *file, unsigned line, unsigned column);
163181
#if SWIFT_OBJC_INTEROP
164182
SWIFT_RUNTIME_EXPORT
165183
const ClassMetadata *
@@ -168,7 +186,8 @@ swift_dynamicCastObjCClassMetatype(const ClassMetadata *sourceType,
168186
SWIFT_RUNTIME_EXPORT
169187
const ClassMetadata *
170188
swift_dynamicCastObjCClassMetatypeUnconditional(const ClassMetadata *sourceType,
171-
const ClassMetadata *targetType);
189+
const ClassMetadata *targetType,
190+
const char *file, unsigned line, unsigned column);
172191
#endif
173192

174193
SWIFT_RUNTIME_EXPORT
@@ -179,7 +198,8 @@ SWIFT_RUNTIME_EXPORT
179198
const ClassMetadata *
180199
swift_dynamicCastForeignClassMetatypeUnconditional(
181200
const ClassMetadata *sourceType,
182-
const ClassMetadata *targetType);
201+
const ClassMetadata *targetType,
202+
const char *file, unsigned line, unsigned column);
183203

184204
/// \brief Return the dynamic type of an opaque value.
185205
///

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ FUNCTION(DynamicCastClass, swift_dynamicCastClass, C_CC,
942942
FUNCTION(DynamicCastClassUnconditional, swift_dynamicCastClassUnconditional,
943943
C_CC,
944944
RETURNS(Int8PtrTy),
945-
ARGS(Int8PtrTy, Int8PtrTy),
945+
ARGS(Int8PtrTy, Int8PtrTy, Int8PtrTy, Int32Ty, Int32Ty),
946946
ATTRS(NoUnwind, ReadOnly))
947947

948948
// void *swift_dynamicCastObjCClass(void*, void*);
@@ -955,7 +955,7 @@ FUNCTION(DynamicCastObjCClass, swift_dynamicCastObjCClass, C_CC,
955955
FUNCTION(DynamicCastObjCClassUnconditional,
956956
swift_dynamicCastObjCClassUnconditional, C_CC,
957957
RETURNS(Int8PtrTy),
958-
ARGS(Int8PtrTy, Int8PtrTy),
958+
ARGS(Int8PtrTy, Int8PtrTy, Int8PtrTy, Int32Ty, Int32Ty),
959959
ATTRS(NoUnwind, ReadOnly))
960960

961961
// void *swift_dynamicCastUnknownClass(void*, void*);
@@ -968,7 +968,7 @@ FUNCTION(DynamicCastUnknownClass, swift_dynamicCastUnknownClass, C_CC,
968968
FUNCTION(DynamicCastUnknownClassUnconditional,
969969
swift_dynamicCastUnknownClassUnconditional, C_CC,
970970
RETURNS(Int8PtrTy),
971-
ARGS(Int8PtrTy, Int8PtrTy),
971+
ARGS(Int8PtrTy, Int8PtrTy, Int8PtrTy, Int32Ty, Int32Ty),
972972
ATTRS(NoUnwind, ReadOnly))
973973

974974
// type *swift_dynamicCastMetatype(type*, type*);
@@ -981,7 +981,7 @@ FUNCTION(DynamicCastMetatype, swift_dynamicCastMetatype, C_CC,
981981
FUNCTION(DynamicCastMetatypeUnconditional,
982982
swift_dynamicCastMetatypeUnconditional, C_CC,
983983
RETURNS(TypeMetadataPtrTy),
984-
ARGS(TypeMetadataPtrTy, TypeMetadataPtrTy),
984+
ARGS(TypeMetadataPtrTy, TypeMetadataPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
985985
ATTRS(NoUnwind, ReadOnly))
986986

987987
// objc_class *swift_dynamicCastObjCClassMetatype(objc_class*, objc_class*);
@@ -995,7 +995,7 @@ FUNCTION(DynamicCastObjCClassMetatype, swift_dynamicCastObjCClassMetatype,
995995
FUNCTION(DynamicCastObjCClassMetatypeUnconditional,
996996
swift_dynamicCastObjCClassMetatypeUnconditional, C_CC,
997997
RETURNS(ObjCClassPtrTy),
998-
ARGS(ObjCClassPtrTy, ObjCClassPtrTy),
998+
ARGS(ObjCClassPtrTy, ObjCClassPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
999999
ATTRS(NoUnwind, ReadOnly))
10001000

10011001
// bool swift_dynamicCast(opaque*, opaque*, type*, type*, size_t);
@@ -1011,7 +1011,7 @@ FUNCTION(DynamicCast, swift_dynamicCast, C_CC,
10111011
FUNCTION(DynamicCastTypeToObjCProtocolUnconditional,
10121012
swift_dynamicCastTypeToObjCProtocolUnconditional, C_CC,
10131013
RETURNS(TypeMetadataPtrTy),
1014-
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy),
1014+
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
10151015
ATTRS(NoUnwind))
10161016

10171017
// type* swift_dynamicCastTypeToObjCProtocolConditional(type* object,
@@ -1029,7 +1029,7 @@ FUNCTION(DynamicCastTypeToObjCProtocolConditional,
10291029
FUNCTION(DynamicCastObjCProtocolUnconditional,
10301030
swift_dynamicCastObjCProtocolUnconditional, C_CC,
10311031
RETURNS(ObjCPtrTy),
1032-
ARGS(ObjCPtrTy, SizeTy, Int8PtrPtrTy),
1032+
ARGS(ObjCPtrTy, SizeTy, Int8PtrPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
10331033
ATTRS(NoUnwind))
10341034

10351035
// id swift_dynamicCastObjCProtocolConditional(id object,
@@ -1045,7 +1045,7 @@ FUNCTION(DynamicCastObjCProtocolConditional,
10451045
FUNCTION(DynamicCastMetatypeToObjectUnconditional,
10461046
swift_dynamicCastMetatypeToObjectUnconditional, C_CC,
10471047
RETURNS(ObjCPtrTy),
1048-
ARGS(TypeMetadataPtrTy),
1048+
ARGS(TypeMetadataPtrTy, Int8PtrTy, Int32Ty, Int32Ty),
10491049
ATTRS(NoUnwind, ReadNone))
10501050

10511051
// id swift_dynamicCastMetatypeToObjectConditional(type *type);

lib/IRGen/GenCast.cpp

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,34 @@ FailableCastResult irgen::emitClassIdenticalCast(IRGenFunction &IGF,
133133
return {cond, from};
134134
}
135135

136+
/// Returns an ArrayRef with the set of arguments to pass to a dynamic cast call.
137+
///
138+
/// `argsBuf` should be passed in as a reference to an array with three nullptr
139+
/// values at the end. These will be dropped from the return ArrayRef for a
140+
/// conditional cast, or filled in with source location arguments for an
141+
/// unconditional cast.
142+
template<unsigned n>
143+
static ArrayRef<llvm::Value*>
144+
getDynamicCastArguments(IRGenFunction &IGF,
145+
llvm::Value *(&argsBuf)[n], CheckedCastMode mode
146+
/*TODO , SILLocation location*/)
147+
{
148+
switch (mode) {
149+
case CheckedCastMode::Unconditional:
150+
// TODO: Pass along location info if available for unconditional casts, so
151+
// that the runtime error for a failed cast can report the source of the
152+
// error from user code.
153+
argsBuf[n-3] = llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
154+
argsBuf[n-2] = llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0);
155+
argsBuf[n-1] = llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0);
156+
return argsBuf;
157+
158+
case CheckedCastMode::Conditional:
159+
return llvm::makeArrayRef(argsBuf, n-3);
160+
break;
161+
}
162+
}
163+
136164
/// Emit a checked unconditional downcast of a class value.
137165
llvm::Value *irgen::emitClassDowncast(IRGenFunction &IGF, llvm::Value *from,
138166
SILType toType, CheckedCastMode mode) {
@@ -206,9 +234,17 @@ llvm::Value *irgen::emitClassDowncast(IRGenFunction &IGF, llvm::Value *from,
206234
if (auto fun = dyn_cast<llvm::Function>(castFn))
207235
cc = fun->getCallingConv();
208236

237+
llvm::Value *argsBuf[] = {
238+
from,
239+
metadataRef,
240+
nullptr,
241+
nullptr,
242+
nullptr,
243+
};
244+
209245
auto call
210-
= IGF.Builder.CreateCall(castFn, {from, metadataRef});
211-
// FIXME: Eventually, we may want to throw.
246+
= IGF.Builder.CreateCall(castFn,
247+
getDynamicCastArguments(IGF, argsBuf, mode));
212248
call->setCallingConv(cc);
213249
call->setDoesNotThrow();
214250

@@ -267,8 +303,17 @@ void irgen::emitMetatypeDowncast(IRGenFunction &IGF,
267303
auto cc = IGF.IGM.DefaultCC;
268304
if (auto fun = dyn_cast<llvm::Function>(castFn))
269305
cc = fun->getCallingConv();
306+
307+
llvm::Value *argsBuf[] = {
308+
metatype,
309+
toMetadata,
310+
nullptr,
311+
nullptr,
312+
nullptr,
313+
};
270314

271-
auto call = IGF.Builder.CreateCall(castFn, {metatype, toMetadata});
315+
auto call = IGF.Builder.CreateCall(castFn,
316+
getDynamicCastArguments(IGF, argsBuf, mode));
272317
call->setCallingConv(cc);
273318
call->setDoesNotThrow();
274319
ex.add(call);
@@ -486,8 +531,16 @@ llvm::Value *irgen::emitMetatypeToAnyObjectDowncast(IRGenFunction &IGF,
486531
auto cc = IGF.IGM.DefaultCC;
487532
if (auto fun = dyn_cast<llvm::Function>(castFn))
488533
cc = fun->getCallingConv();
489-
490-
auto call = IGF.Builder.CreateCall(castFn, metatypeValue);
534+
535+
llvm::Value *argsBuf[] = {
536+
metatypeValue,
537+
nullptr,
538+
nullptr,
539+
nullptr,
540+
};
541+
542+
auto call = IGF.Builder.CreateCall(castFn,
543+
getDynamicCastArguments(IGF, argsBuf, mode));
491544
call->setCallingConv(cc);
492545
return call;
493546
}
@@ -672,11 +725,18 @@ void irgen::emitScalarExistentialDowncast(IRGenFunction &IGF,
672725
if (auto fun = dyn_cast<llvm::Function>(castFn))
673726
cc = fun->getCallingConv();
674727

728+
llvm::Value *argsBuf[] = {
729+
objcCastObject,
730+
IGF.IGM.getSize(Size(objcProtos.size())),
731+
protoRefsBuf.getAddress(),
732+
nullptr,
733+
nullptr,
734+
nullptr,
735+
};
675736

676737
auto call = IGF.Builder.CreateCall(
677-
castFn,
678-
{objcCastObject, IGF.IGM.getSize(Size(objcProtos.size())),
679-
protoRefsBuf.getAddress()});
738+
castFn,
739+
getDynamicCastArguments(IGF, argsBuf, mode));
680740
call->setCallingConv(cc);
681741
objcCast = call;
682742
resultValue = IGF.Builder.CreateBitCast(objcCast, resultType);

0 commit comments

Comments
 (0)