@@ -28,10 +28,10 @@ using namespace Lowering;
28
28
// / object, using the appropriate witness for the
29
29
// / _ObjectiveCBridgeable._bridgeToObjectiveC requirement.
30
30
static Optional<ManagedValue>
31
- emitBridgeToObjectiveC (SILGenFunction &gen,
32
- SILLocation loc,
33
- ManagedValue swiftValue,
34
- ProtocolConformance *conformance) {
31
+ emitBridgeNativeToObjectiveC (SILGenFunction &gen,
32
+ SILLocation loc,
33
+ ManagedValue swiftValue,
34
+ ProtocolConformance *conformance) {
35
35
// Dig out the nominal type we're bridging from.
36
36
Type swiftValueType = swiftValue.getSwiftType ()->getRValueType ();
37
37
@@ -80,9 +80,10 @@ emitBridgeToObjectiveC(SILGenFunction &gen,
80
80
// / Bridge the given Swift value to its corresponding Objective-C
81
81
// / object, using the appropriate witness for the
82
82
// / _ObjectiveCBridgeable._bridgeToObjectiveC requirement.
83
- static Optional<ManagedValue> emitBridgeToObjectiveC (SILGenFunction &gen,
84
- SILLocation loc,
85
- ManagedValue swiftValue) {
83
+ static Optional<ManagedValue>
84
+ emitBridgeNativeToObjectiveC (SILGenFunction &gen,
85
+ SILLocation loc,
86
+ ManagedValue swiftValue) {
86
87
// Dig out the nominal type we're bridging from.
87
88
Type swiftValueType = swiftValue.getSwiftType ()->getRValueType ();
88
89
@@ -91,7 +92,7 @@ static Optional<ManagedValue> emitBridgeToObjectiveC(SILGenFunction &gen,
91
92
gen.SGM .getConformanceToObjectiveCBridgeable (loc, swiftValueType);
92
93
if (!conformance) return None;
93
94
94
- return emitBridgeToObjectiveC (gen, loc, swiftValue, conformance);
95
+ return emitBridgeNativeToObjectiveC (gen, loc, swiftValue, conformance);
95
96
}
96
97
97
98
static ManagedValue emitBridgeStringToNSString (SILGenFunction &gen,
@@ -100,26 +101,80 @@ static ManagedValue emitBridgeStringToNSString(SILGenFunction &gen,
100
101
llvm_unreachable (" Handled via the _bridgeToObjectiveC witness" );
101
102
}
102
103
103
- static ManagedValue emitBridgeNSStringToString (SILGenFunction &gen,
104
- SILLocation loc,
105
- ManagedValue nsstr) {
106
- SILValue bridgeFn =
107
- gen.emitGlobalFunctionRef (loc, gen.SGM .getNSStringToStringFn ());
104
+ // / Bridge the given Objective-C object to its corresponding Swift
105
+ // / value, using the appropriate witness for the
106
+ // / _ObjectiveCBridgeable._unconditionallyBridgeFromObjectiveC requirement.
107
+ static Optional<ManagedValue>
108
+ emitBridgeObjectiveCToNative (SILGenFunction &gen,
109
+ SILLocation loc,
110
+ ManagedValue objcValue,
111
+ ProtocolConformance *conformance) {
112
+ // Find the _unconditionallyBridgeFromObjectiveC requirement.
113
+ auto requirement =
114
+ gen.SGM .getUnconditionallyBridgeFromObjectiveCRequirement (loc);
115
+ if (!requirement) return None;
108
116
109
- Type inputType = nsstr.getType ().getSwiftRValueType ();
110
- if (!inputType->getOptionalObjectType ()) {
111
- SILType loweredOptTy = gen.SGM .getLoweredType (OptionalType::get (inputType));
117
+ // Retrieve the _unconditionallyBridgeFromObjectiveC witness.
118
+ auto witness = conformance->getWitness (requirement, nullptr );
119
+ assert (witness);
120
+
121
+ // Create a reference to the witness.
122
+ SILDeclRef witnessConstant (witness.getDecl ());
123
+ auto witnessRef = gen.emitGlobalFunctionRef (loc, witnessConstant);
124
+
125
+ // Determine the substitutions.
126
+ ArrayRef<Substitution> substitutions;
127
+ auto witnessFnTy = witnessRef->getType ().castTo <SILFunctionType>();
128
+
129
+ Type swiftValueType = conformance->getType ();
130
+ if (auto valueTypeBGT = swiftValueType->getAs <BoundGenericType>()) {
131
+ // Compute the substitutions.
132
+ substitutions = valueTypeBGT->getSubstitutions (gen.SGM .SwiftModule ,
133
+ nullptr );
134
+ }
135
+
136
+ // Substitute into the witness function type.
137
+ if (!substitutions.empty ())
138
+ witnessFnTy = witnessFnTy->substGenericArgs (gen.SGM .M , gen.SGM .SwiftModule ,
139
+ substitutions);
140
+
141
+ // If the Objective-C value isn't optional, wrap it in an optional.
142
+ Type objcValueType = objcValue.getType ().getSwiftRValueType ();
143
+ if (!objcValueType->getOptionalObjectType ()) {
144
+ SILType loweredOptTy =
145
+ gen.SGM .getLoweredType (OptionalType::get (objcValueType));
112
146
auto *someDecl = gen.getASTContext ().getOptionalSomeDecl ();
113
- auto *enumInst = gen.B .createEnum (loc, nsstr .getValue (), someDecl,
147
+ auto *enumInst = gen.B .createEnum (loc, objcValue .getValue (), someDecl,
114
148
loweredOptTy);
115
- nsstr = ManagedValue (enumInst, nsstr .getCleanup ());
149
+ objcValue = ManagedValue (enumInst, objcValue .getCleanup ());
116
150
}
117
151
118
- SILType nativeTy = gen.getLoweredType (gen.SGM .Types .getStringType ());
119
- SILValue str = gen.B .createApply (loc, bridgeFn, bridgeFn->getType (), nativeTy,
120
- {}, { nsstr.forward (gen) });
121
-
122
- return gen.emitManagedRValueWithCleanup (str);
152
+ // Call the witness.
153
+ Type metatype = MetatypeType::get (swiftValueType);
154
+ SILValue metatypeValue = gen.B .createMetatype (loc,
155
+ gen.getLoweredType (metatype));
156
+
157
+ auto witnessCI = gen.getConstantInfo (witnessConstant);
158
+ CanType formalResultTy = witnessCI.LoweredInterfaceType .getResult ();
159
+
160
+ // Set up the generic signature.
161
+ CanGenericSignature witnessGenericSignature;
162
+ if (auto genericSig =
163
+ cast<AbstractFunctionDecl>(witness.getDecl ())->getGenericSignature ())
164
+ witnessGenericSignature = genericSig->getCanonicalSignature ();
165
+
166
+ GenericContextScope genericContextScope (gen.SGM .Types ,
167
+ witnessGenericSignature);
168
+ return gen.emitApply (loc, ManagedValue::forUnmanaged (witnessRef),
169
+ substitutions,
170
+ { objcValue, ManagedValue::forUnmanaged (metatypeValue) },
171
+ witnessFnTy,
172
+ AbstractionPattern (witnessGenericSignature,
173
+ formalResultTy),
174
+ swiftValueType->getCanonicalType (),
175
+ ApplyOptions::None, None, None,
176
+ SGFContext ())
177
+ .getAsSingleValue (gen, loc);
123
178
}
124
179
125
180
static ManagedValue emitBridgeCollectionToNative (SILGenFunction &gen,
@@ -376,7 +431,7 @@ static ManagedValue emitNativeToCBridgedNonoptionalValue(SILGenFunction &gen,
376
431
// hardcoding String -> NSString.
377
432
if (loweredNativeTy == gen.SGM .Types .getStringType ()
378
433
&& loweredBridgedTy == gen.SGM .Types .getNSStringType ()) {
379
- if (auto result = emitBridgeToObjectiveC (gen, loc, v))
434
+ if (auto result = emitBridgeNativeToObjectiveC (gen, loc, v))
380
435
return *result;
381
436
382
437
return gen.emitUndef (loc, bridgedTy);
@@ -413,7 +468,7 @@ static ManagedValue emitNativeToCBridgedNonoptionalValue(SILGenFunction &gen,
413
468
// _bridgeToObjectiveC witness.
414
469
if (auto conformance =
415
470
gen.SGM .getConformanceToObjectiveCBridgeable (loc, loweredNativeTy)) {
416
- if (auto result = emitBridgeToObjectiveC (gen, loc, v, conformance))
471
+ if (auto result = emitBridgeNativeToObjectiveC (gen, loc, v, conformance))
417
472
return *result;
418
473
419
474
return gen.emitUndef (loc, bridgedTy);
@@ -607,7 +662,14 @@ static ManagedValue emitCBridgedToNativeValue(SILGenFunction &gen,
607
662
// Bridge NSString to String.
608
663
if (auto stringDecl = gen.getASTContext ().getStringDecl ()) {
609
664
if (nativeTy.getSwiftRValueType ()->getAnyNominal () == stringDecl) {
610
- return emitBridgeNSStringToString (gen, loc, v);
665
+ auto conformance =
666
+ gen.SGM .getConformanceToObjectiveCBridgeable (loc, loweredNativeTy);
667
+ assert (conformance &&
668
+ " Missing String conformation to _ObjectiveCBridgeable?" );
669
+ if (auto result = emitBridgeObjectiveCToNative (gen, loc, v, conformance))
670
+ return *result;
671
+
672
+ return gen.emitUndef (loc, nativeTy);
611
673
}
612
674
}
613
675
0 commit comments