@@ -1331,8 +1331,8 @@ static SILFunctionType *
1331
1331
emitObjCThunkArguments (SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk,
1332
1332
SmallVectorImpl<SILValue> &args,
1333
1333
SILValue &foreignErrorSlot, SILValue &foreignAsyncSlot,
1334
- std::optional<ForeignErrorConvention> & foreignError,
1335
- std::optional<ForeignAsyncConvention> & foreignAsync,
1334
+ std::optional<ForeignErrorConvention> foreignError,
1335
+ std::optional<ForeignAsyncConvention> foreignAsync,
1336
1336
CanType &nativeFormalResultTy,
1337
1337
CanType &bridgedFormalResultTy) {
1338
1338
SILDeclRef native = thunk.asForeign (false );
@@ -1355,18 +1355,6 @@ emitObjCThunkArguments(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk,
1355
1355
SmallVector<ManagedValue, 8 > bridgedArgs;
1356
1356
bridgedArgs.reserve (objcFnTy->getParameters ().size ());
1357
1357
1358
- // Find the foreign error and async conventions if we have one.
1359
- if (thunk.hasDecl ()) {
1360
- if (auto func = dyn_cast<AbstractFunctionDecl>(thunk.getDecl ())) {
1361
- foreignError = func->getForeignErrorConvention ();
1362
- foreignAsync = func->getForeignAsyncConvention ();
1363
- }
1364
- }
1365
-
1366
- // We don't know what to do with indirect results from the Objective-C side.
1367
- assert (objcFnTy->getNumIndirectFormalResults () == 0
1368
- && " Objective-C methods cannot have indirect results" );
1369
-
1370
1358
auto bridgedFormalTypes = getParameterTypes (objcFormalFnTy.getParams ());
1371
1359
bridgedFormalResultTy = objcFormalFnTy.getResult ();
1372
1360
@@ -1618,16 +1606,40 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1618
1606
}
1619
1607
}
1620
1608
1609
+ std::optional<ForeignErrorConvention> foreignError;
1610
+ std::optional<ForeignAsyncConvention> foreignAsync;
1611
+
1612
+ // Find the foreign error and async conventions if we have one.
1613
+ if (thunk.hasDecl ()) {
1614
+ if (auto func = dyn_cast<AbstractFunctionDecl>(thunk.getDecl ())) {
1615
+ foreignError = func->getForeignErrorConvention ();
1616
+ foreignAsync = func->getForeignAsyncConvention ();
1617
+ }
1618
+ }
1619
+
1621
1620
// If we are bridging a Swift method with Any return value(s), create a
1622
1621
// stack allocation to hold the result(s), since Any is address-only.
1623
1622
SmallVector<SILValue, 4 > args;
1623
+ SILFunctionConventions funcConv = F.getConventions ();
1624
+ bool needsBridging = true ;
1624
1625
if (substConv.hasIndirectSILResults ()) {
1625
1626
for (auto result : substConv.getResults ()) {
1626
1627
if (!substConv.isSILIndirect (result)) {
1627
1628
continue ;
1628
1629
}
1630
+
1631
+ if (!foreignAsync && funcConv.hasIndirectSILResults ()) {
1632
+ auto resultTy =
1633
+ funcConv.getSingleSILResultType (getTypeExpansionContext ());
1634
+ assert (substConv.getSingleSILResultType (getTypeExpansionContext ()) ==
1635
+ resultTy);
1636
+ args.push_back (F.begin ()->createFunctionArgument (resultTy));
1637
+ needsBridging = false ;
1638
+ break ;
1639
+ }
1640
+
1629
1641
args.push_back (emitTemporaryAllocation (
1630
- loc, substConv.getSILType (result, getTypeExpansionContext ())));
1642
+ loc, substConv.getSILType (result, getTypeExpansionContext ())));
1631
1643
}
1632
1644
}
1633
1645
@@ -1637,8 +1649,6 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1637
1649
Scope argScope (Cleanups, CleanupLocation (loc));
1638
1650
1639
1651
// Bridge the arguments.
1640
- std::optional<ForeignErrorConvention> foreignError;
1641
- std::optional<ForeignAsyncConvention> foreignAsync;
1642
1652
SILValue foreignErrorSlot;
1643
1653
SILValue foreignAsyncSlot;
1644
1654
CanType nativeFormalResultType, bridgedFormalResultType;
@@ -1872,12 +1882,14 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1872
1882
if (foreignAsync) {
1873
1883
result = passResultToCompletionHandler (result);
1874
1884
} else {
1875
- if (substConv.hasIndirectSILResults ()) {
1876
- assert (substTy->getNumResults () == 1 );
1877
- result = args[0 ];
1885
+ if (needsBridging) {
1886
+ if (substConv.hasIndirectSILResults ()) {
1887
+ assert (substTy->getNumResults () == 1 );
1888
+ result = args[0 ];
1889
+ }
1890
+ result = emitBridgeReturnValue (*this , loc, result, nativeFormalResultType,
1891
+ bridgedFormalResultType, objcResultTy);
1878
1892
}
1879
- result = emitBridgeReturnValue (*this , loc, result, nativeFormalResultType,
1880
- bridgedFormalResultType, objcResultTy);
1881
1893
}
1882
1894
} else {
1883
1895
SILBasicBlock *contBB = createBasicBlock ();
0 commit comments