@@ -1593,13 +1593,17 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1593
1593
}
1594
1594
}
1595
1595
1596
- // If we are bridging a Swift method with an Any return value, create a
1597
- // stack allocation to hold the result, since Any is address-only.
1596
+ // If we are bridging a Swift method with Any return value(s) , create a
1597
+ // stack allocation to hold the result(s) , since Any is address-only.
1598
1598
SmallVector<SILValue, 4 > args;
1599
-
1600
1599
if (substConv.hasIndirectSILResults ()) {
1601
- args.push_back (emitTemporaryAllocation (
1602
- loc, substConv.getSingleSILResultType (getTypeExpansionContext ())));
1600
+ for (auto result : substConv.getResults ()) {
1601
+ if (!substConv.isSILIndirect (result)) {
1602
+ continue ;
1603
+ }
1604
+ args.push_back (emitTemporaryAllocation (
1605
+ loc, substConv.getSILType (result, getTypeExpansionContext ())));
1606
+ }
1603
1607
}
1604
1608
1605
1609
// If the '@objc' was inferred due to deprecated rules,
@@ -1792,14 +1796,29 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1792
1796
pushErrorFlag (/* has error*/ false , completionHandlerArgs);
1793
1797
continue ;
1794
1798
}
1795
- pushArg (asyncResult,
1796
- nativeFormalResultType,
1797
- completionTy->getParameters ()[i]);
1799
+
1800
+ // Use the indirect return argument if the result is indirect.
1801
+ if (substConv.hasIndirectSILResults ()) {
1802
+ pushArg (emitManagedRValueWithCleanup (args[0 ]),
1803
+ nativeFormalResultType,
1804
+ completionTy->getParameters ()[i]);
1805
+ } else {
1806
+ pushArg (asyncResult,
1807
+ nativeFormalResultType,
1808
+ completionTy->getParameters ()[i]);
1809
+ }
1798
1810
}
1799
1811
} else {
1800
1812
// A tuple return maps to multiple completion handler parameters.
1801
1813
auto formalTuple = cast<TupleType>(nativeFormalResultType);
1802
1814
1815
+ unsigned indirectResultI = 0 ;
1816
+ unsigned directResultI = 0 ;
1817
+
1818
+ auto directResults = substConv.getDirectSILResults ();
1819
+ auto hasMultipleDirectResults
1820
+ = std::next (directResults.begin ()) != directResults.end ();
1821
+
1803
1822
for (unsigned paramI : indices (completionTy->getParameters ())) {
1804
1823
if (errorParamIndex && paramI == *errorParamIndex) {
1805
1824
pushErrorPlaceholder ();
@@ -1813,7 +1832,21 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1813
1832
- (errorFlagIndex && paramI > *errorFlagIndex);
1814
1833
auto param = completionTy->getParameters ()[paramI];
1815
1834
auto formalTy = formalTuple.getElementType (elementI);
1816
- auto argPiece = B.createTupleExtract (loc, asyncResult, elementI);
1835
+ ManagedValue argPiece;
1836
+
1837
+ auto result = substConv.getResults ()[elementI];
1838
+ if (substConv.isSILIndirect (result)) {
1839
+ // Take the arg piece from the indirect return arguments.
1840
+ argPiece = emitManagedRValueWithCleanup (args[indirectResultI++]);
1841
+ } else if (hasMultipleDirectResults) {
1842
+ // Take the arg piece from one of the tuple elements of the direct
1843
+ // result tuple from the apply.
1844
+ argPiece = B.createTupleExtract (loc, asyncResult, directResultI++);
1845
+ } else {
1846
+ // Take the entire direct result from the apply as the arg piece.
1847
+ argPiece = asyncResult;
1848
+ }
1849
+
1817
1850
pushArg (argPiece, formalTy, param);
1818
1851
}
1819
1852
}
@@ -1829,16 +1862,11 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1829
1862
// The immediate function result is an empty tuple.
1830
1863
return SILUndef::get (SGM.Types .getEmptyTupleType (), F);
1831
1864
};
1832
-
1865
+
1833
1866
if (!substTy->hasErrorResult ()) {
1834
1867
// Create the apply.
1835
1868
result = B.createApply (loc, nativeFn, subs, args);
1836
-
1837
- if (substConv.hasIndirectSILResults ()) {
1838
- assert (substTy->getNumResults () == 1 );
1839
- result = args[0 ];
1840
- }
1841
-
1869
+
1842
1870
// Leave the argument cleanup scope immediately. This isn't really
1843
1871
// necessary; it just limits lifetimes a little bit more.
1844
1872
argScope.pop ();
@@ -1849,6 +1877,10 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1849
1877
if (foreignAsync) {
1850
1878
result = passResultToCompletionHandler (result);
1851
1879
} else {
1880
+ if (substConv.hasIndirectSILResults ()) {
1881
+ assert (substTy->getNumResults () == 1 );
1882
+ result = args[0 ];
1883
+ }
1852
1884
result = emitBridgeReturnValue (*this , loc, result, nativeFormalResultType,
1853
1885
bridgedFormalResultType, objcResultTy);
1854
1886
}
@@ -1864,17 +1896,16 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1864
1896
SILValue nativeResult =
1865
1897
normalBB->createPhiArgument (swiftResultTy, OwnershipKind::Owned);
1866
1898
1867
- if (substConv.hasIndirectSILResults ()) {
1868
- assert (substTy->getNumResults () == 1 );
1869
- nativeResult = args[0 ];
1870
- }
1871
-
1872
1899
if (foreignAsync) {
1873
1900
// If the function is async, pass the results as the success argument(s)
1874
1901
// to the completion handler, with a nil error.
1875
1902
passResultToCompletionHandler (nativeResult);
1876
1903
B.createBranch (loc, contBB);
1877
1904
} else {
1905
+ if (substConv.hasIndirectSILResults ()) {
1906
+ assert (substTy->getNumResults () == 1 );
1907
+ nativeResult = args[0 ];
1908
+ }
1878
1909
// In this branch, the eventual return value is mostly created
1879
1910
// by bridging the native return value, but we may need to
1880
1911
// adjust it slightly.
0 commit comments