@@ -1684,6 +1684,19 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1684
1684
}
1685
1685
};
1686
1686
1687
+ auto pushErrorFlag = [&](bool hasError,
1688
+ SmallVectorImpl<SILValue> &completionHandlerArgs) {
1689
+ bool errorFlagIsZeroOnError = foreignAsync->completionHandlerFlagIsErrorOnZero ();
1690
+ auto errorFlagIndex = foreignAsync->completionHandlerFlagParamIndex ();
1691
+ auto errorFlagTy = completionTy->getParameters ()[*errorFlagIndex]
1692
+ .getSILStorageInterfaceType ();
1693
+
1694
+ auto errorFlag = emitWrapIntegerLiteral (loc, errorFlagTy,
1695
+ hasError ^ errorFlagIsZeroOnError);
1696
+
1697
+ completionHandlerArgs.push_back (errorFlag);
1698
+ };
1699
+
1687
1700
// Helper function to pass a native async function's result as arguments to
1688
1701
// the ObjC completion handler block.
1689
1702
auto passResultToCompletionHandler = [&](SILValue result) -> SILValue {
@@ -1711,6 +1724,7 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1711
1724
Scope completionArgDestructureScope (*this , loc);
1712
1725
1713
1726
auto errorParamIndex = foreignAsync->completionHandlerErrorParamIndex ();
1727
+ auto errorFlagIndex = foreignAsync->completionHandlerFlagParamIndex ();
1714
1728
auto pushErrorPlaceholder = [&]{
1715
1729
auto errorArgTy = completionTy->getParameters ()[*errorParamIndex]
1716
1730
.getSILStorageInterfaceType ();
@@ -1721,18 +1735,22 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1721
1735
};
1722
1736
1723
1737
unsigned numResults
1724
- = completionTy->getParameters ().size () - errorParamIndex.hasValue ();
1738
+ = completionTy->getParameters ().size () - errorParamIndex.hasValue ()
1739
+ - errorFlagIndex.hasValue ();
1725
1740
1726
1741
if (numResults == 1 ) {
1727
- if (errorParamIndex && *errorParamIndex == 0 ) {
1728
- pushErrorPlaceholder ();
1729
- }
1730
- pushArg (asyncResult,
1731
- nativeFormalResultType,
1732
- completionTy->getParameters ()[completionHandlerArgs.size ()]);
1733
-
1734
- if (errorParamIndex && *errorParamIndex == 1 ) {
1735
- pushErrorPlaceholder ();
1742
+ for (unsigned i = 0 ; i < completionTy->getNumParameters (); ++i) {
1743
+ if (errorParamIndex && *errorParamIndex == i) {
1744
+ pushErrorPlaceholder ();
1745
+ continue ;
1746
+ }
1747
+ if (errorFlagIndex && *errorFlagIndex == i) {
1748
+ pushErrorFlag (/* has error*/ false , completionHandlerArgs);
1749
+ continue ;
1750
+ }
1751
+ pushArg (asyncResult,
1752
+ nativeFormalResultType,
1753
+ completionTy->getParameters ()[i]);
1736
1754
}
1737
1755
} else {
1738
1756
// A tuple return maps to multiple completion handler parameters.
@@ -1743,7 +1761,12 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1743
1761
pushErrorPlaceholder ();
1744
1762
continue ;
1745
1763
}
1746
- auto elementI = paramI - (errorParamIndex && paramI > *errorParamIndex);
1764
+ if (errorFlagIndex && paramI == *errorFlagIndex) {
1765
+ pushErrorFlag (/* has error*/ false , completionHandlerArgs);
1766
+ continue ;
1767
+ }
1768
+ auto elementI = paramI - (errorParamIndex && paramI > *errorParamIndex)
1769
+ - (errorFlagIndex && paramI > *errorFlagIndex);
1747
1770
auto param = completionTy->getParameters ()[paramI];
1748
1771
auto formalTy = formalTuple.getElementType (elementI);
1749
1772
auto argPiece = B.createTupleExtract (loc, asyncResult, elementI);
@@ -1845,6 +1868,7 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1845
1868
SmallVector<SILValue, 2 > completionHandlerArgs;
1846
1869
auto completionTy = completionBlock->getType ().castTo <SILFunctionType>();
1847
1870
auto errorParamIndex = *foreignAsync->completionHandlerErrorParamIndex ();
1871
+ auto errorFlagIndex = foreignAsync->completionHandlerFlagParamIndex ();
1848
1872
auto completionErrorTy = completionTy->getParameters ()[errorParamIndex]
1849
1873
.getInterfaceType ();
1850
1874
auto bridgedError = emitNativeToBridgedError (loc,
@@ -1860,6 +1884,11 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
1860
1884
continue ;
1861
1885
}
1862
1886
1887
+ if (errorFlagIndex && i == *errorFlagIndex) {
1888
+ pushErrorFlag (/* has error*/ true , completionHandlerArgs);
1889
+ continue ;
1890
+ }
1891
+
1863
1892
// For non-error arguments, pass a placeholder.
1864
1893
// If the argument type is non-trivial, it must be Optional, and
1865
1894
// we pass nil.
0 commit comments