Skip to content

Commit 67f7e77

Browse files
slavapestovjckarter
authored andcommitted
Runtime: Add preliminary _swift_bridgeUnknownToObject() entry point.
1 parent d1e0f51 commit 67f7e77

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

stdlib/public/core/BridgeObjectiveC.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,33 @@ func _bridgeToObjectiveCUnconditionalAutorelease<T>(_ x: T) -> AnyObject
193193
@_silgen_name("_swift_bridgeNonVerbatimToObjectiveC")
194194
func _bridgeNonVerbatimToObjectiveC<T>(_ x: T) -> AnyObject?
195195

196+
/// Bridge an arbitrary value to an Objective-C object.
197+
///
198+
/// - If `T` is a class type, it is always bridged verbatim, the function
199+
/// returns `x`;
200+
///
201+
/// - otherwise, `T` conforms to `_ObjectiveCBridgeable`:
202+
/// + if `T._isBridgedToObjectiveC()` returns `false`, then
203+
/// we fall back to boxing (below);
204+
/// + otherwise, returns the result of `x._bridgeToObjectiveC()`;
205+
///
206+
/// - otherwise, we use **boxing** to bring the value into Objective-C.
207+
/// The value is wrapped in an instance of a private Objective-C class
208+
/// that is `id`-compatible and dynamically castable back to the type of
209+
/// the boxed value, but is otherwise opaque.
210+
///
211+
/// TODO: This should subsume `_bridgeToObjectiveC` above.
212+
func _bridgeAnythingToObjectiveC<T>(_: T) -> AnyObject {
213+
if _fastPath(_isClassOrObjCExistential(T.self)) {
214+
return unsafeBitCast(x, to: AnyObject.self)
215+
}
216+
return _bridgeAnythingNonVerbatimToObjectiveC(x)
217+
}
218+
219+
// TODO: This should subsume `_bridgeNonVerbatimToObjectiveC` above.
220+
@_silgen_name("_swift_bridgeAnythingNonVerbatimToObjectiveC")
221+
func _bridgeAnythingNonVerbatimToObjectiveC<T>(_ x: T) -> AnyObject
222+
196223
/// Convert `x` from its Objective-C representation to its Swift
197224
/// representation.
198225
///
@@ -523,4 +550,5 @@ extension AutoreleasingUnsafeMutablePointer {
523550
Builtin.unreachable()
524551
}
525552
}
553+
526554
#endif

stdlib/public/runtime/Casting.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,38 @@ static bool _dynamicCastClassToValueViaObjCBridgeable(
25152515
return success;
25162516
}
25172517

2518+
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
2519+
extern "C"
2520+
id _swift_bridgeAnythingNonVerbatimToObjectiveC(OpaqueValue *src,
2521+
const Metadata *srcType) {
2522+
// We can always bridge objects verbatim.
2523+
if (srcType->isAnyClass()) {
2524+
return *(id*)src;
2525+
}
2526+
2527+
// TODO: Look through existential containers.
2528+
2529+
if (auto srcBridgeWitness = findBridgeWitness(srcType)) {
2530+
// Check whether the source is bridged to Objective-C.
2531+
if (!srcBridgeWitness->isBridgedToObjectiveC(srcType, srcType,
2532+
srcBridgeWitness)) {
2533+
return nil;
2534+
}
2535+
2536+
// Bridge the source value to an object.
2537+
auto srcBridgedObject =
2538+
srcBridgeWitness->bridgeToObjectiveC(src, srcType, srcBridgeWitness);
2539+
2540+
// The source object was passed in +1.
2541+
srcType->vw_destroy(src);
2542+
2543+
return (id)srcBridgedObject;
2544+
}
2545+
2546+
// TODO: Fall back to boxing here.
2547+
crash("unimplemented universal bridging conversion");
2548+
}
2549+
25182550
//===--- Bridging helpers for the Swift stdlib ----------------------------===//
25192551
// Functions that must discover and possibly use an arbitrary type's
25202552
// conformance to a given protocol. See ../core/BridgeObjectiveC.swift for

0 commit comments

Comments
 (0)