@@ -181,6 +181,28 @@ AsyncContextLayout irgen::getAsyncContextLayout(
181
181
paramInfos.push_back ({ty, parameter.getConvention ()});
182
182
}
183
183
184
+ Optional<AsyncContextLayout::TrailingWitnessInfo> trailingWitnessInfo;
185
+ if (originalType->getRepresentation () ==
186
+ SILFunctionTypeRepresentation::WitnessMethod) {
187
+ assert (getTrailingWitnessSignatureLength (IGF.IGM , originalType) == 2 );
188
+
189
+ // First, the Self metadata.
190
+ {
191
+ auto ty = SILType ();
192
+ auto &ti = IGF.IGM .getTypeMetadataPtrTypeInfo ();
193
+ valTypes.push_back (ty);
194
+ typeInfos.push_back (&ti);
195
+ }
196
+ // Then, the Self witness table.
197
+ {
198
+ auto ty = SILType ();
199
+ auto &ti = IGF.IGM .getWitnessTablePtrTypeInfo ();
200
+ valTypes.push_back (ty);
201
+ typeInfos.push_back (&ti);
202
+ }
203
+ trailingWitnessInfo = AsyncContextLayout::TrailingWitnessInfo ();
204
+ }
205
+
184
206
// ResultTypes directResults...;
185
207
auto directResults = fnConv.getDirectSILResults ();
186
208
for (auto result : directResults) {
@@ -192,20 +214,20 @@ AsyncContextLayout irgen::getAsyncContextLayout(
192
214
directReturnInfos.push_back (result);
193
215
}
194
216
195
- return AsyncContextLayout (IGF. IGM , LayoutStrategy::Optimal, valTypes,
196
- typeInfos, IGF, originalType, substitutedType ,
197
- substitutionMap, std::move (bindings), errorType ,
198
- canHaveValidError, paramInfos, indirectReturnInfos ,
199
- directReturnInfos, localContextInfo);
217
+ return AsyncContextLayout (
218
+ IGF. IGM , LayoutStrategy::Optimal, valTypes, typeInfos, IGF, originalType,
219
+ substitutedType, substitutionMap, std::move (bindings),
220
+ trailingWitnessInfo, errorType, canHaveValidError, paramInfos,
221
+ indirectReturnInfos, directReturnInfos, localContextInfo);
200
222
}
201
223
202
224
AsyncContextLayout::AsyncContextLayout (
203
225
IRGenModule &IGM, LayoutStrategy strategy, ArrayRef<SILType> fieldTypes,
204
226
ArrayRef<const TypeInfo *> fieldTypeInfos, IRGenFunction &IGF,
205
227
CanSILFunctionType originalType, CanSILFunctionType substitutedType,
206
228
SubstitutionMap substitutionMap, NecessaryBindings &&bindings,
207
- SILType errorType, bool canHaveValidError ,
208
- ArrayRef<ArgumentInfo> argumentInfos,
229
+ Optional<TrailingWitnessInfo> trailingWitnessInfo, SILType errorType ,
230
+ bool canHaveValidError, ArrayRef<ArgumentInfo> argumentInfos,
209
231
ArrayRef<SILResultInfo> indirectReturnInfos,
210
232
ArrayRef<SILResultInfo> directReturnInfos,
211
233
Optional<AsyncContextLayout::ArgumentInfo> localContextInfo)
@@ -218,6 +240,7 @@ AsyncContextLayout::AsyncContextLayout(
218
240
indirectReturnInfos(indirectReturnInfos.begin(),
219
241
indirectReturnInfos.end()),
220
242
localContextInfo(localContextInfo), bindings(std::move(bindings)),
243
+ trailingWitnessInfo(trailingWitnessInfo),
221
244
argumentInfos(argumentInfos.begin(), argumentInfos.end()) {
222
245
#ifndef NDEBUG
223
246
assert (fieldTypeInfos.size () == fieldTypes.size () &&
@@ -1929,6 +1952,17 @@ class AsyncCallEmission final : public CallEmission {
1929
1952
getCallee ().getSubstitutions ());
1930
1953
}
1931
1954
1955
+ void saveValue (ElementLayout layout, Explosion &explosion, bool isOutlined) {
1956
+ Address addr = layout.project (IGF, context, /* offsets*/ llvm::None);
1957
+ auto &ti = cast<LoadableTypeInfo>(layout.getType ());
1958
+ ti.initialize (IGF, explosion, addr, isOutlined);
1959
+ }
1960
+ void loadValue (ElementLayout layout, Explosion &explosion) {
1961
+ Address addr = layout.project (IGF, context, /* offsets*/ llvm::None);
1962
+ auto &ti = layout.getType ();
1963
+ cast<LoadableTypeInfo>(ti).loadAsTake (IGF, addr, explosion);
1964
+ }
1965
+
1932
1966
public:
1933
1967
AsyncCallEmission (IRGenFunction &IGF, llvm::Value *selfValue, Callee &&callee)
1934
1968
: CallEmission(IGF, selfValue, std::move(callee)) {
@@ -1974,21 +2008,15 @@ class AsyncCallEmission final : public CallEmission {
1974
2008
llArgs.add (selfValue);
1975
2009
}
1976
2010
auto layout = getAsyncContextLayout ();
1977
- for (unsigned index = 0 , count = layout.getArgumentCount (); index < count;
1978
- ++index) {
1979
- auto fieldLayout = layout.getArgumentLayout (index);
1980
- Address fieldAddr =
1981
- fieldLayout.project (IGF, context, /* offsets*/ llvm::None);
1982
- auto &ti = cast<LoadableTypeInfo>(fieldLayout.getType ());
1983
- ti.initialize (IGF, llArgs, fieldAddr, isOutlined);
1984
- }
1985
2011
for (unsigned index = 0 , count = layout.getIndirectReturnCount ();
1986
2012
index < count; ++index) {
1987
2013
auto fieldLayout = layout.getIndirectReturnLayout (index);
1988
- Address fieldAddr =
1989
- fieldLayout.project (IGF, context, /* offsets*/ llvm::None);
1990
- cast<LoadableTypeInfo>(fieldLayout.getType ())
1991
- .initialize (IGF, llArgs, fieldAddr, isOutlined);
2014
+ saveValue (fieldLayout, llArgs, isOutlined);
2015
+ }
2016
+ for (unsigned index = 0 , count = layout.getArgumentCount (); index < count;
2017
+ ++index) {
2018
+ auto fieldLayout = layout.getArgumentLayout (index);
2019
+ saveValue (fieldLayout, llArgs, isOutlined);
1992
2020
}
1993
2021
if (layout.hasBindings ()) {
1994
2022
auto bindingLayout = layout.getBindingsLayout ();
@@ -1997,10 +2025,7 @@ class AsyncCallEmission final : public CallEmission {
1997
2025
}
1998
2026
if (selfValue) {
1999
2027
auto fieldLayout = layout.getLocalContextLayout ();
2000
- Address fieldAddr =
2001
- fieldLayout.project (IGF, context, /* offsets*/ llvm::None);
2002
- auto &ti = cast<LoadableTypeInfo>(fieldLayout.getType ());
2003
- ti.initialize (IGF, llArgs, fieldAddr, isOutlined);
2028
+ saveValue (fieldLayout, llArgs, isOutlined);
2004
2029
}
2005
2030
}
2006
2031
void emitCallToUnmappedExplosion (llvm::CallInst *call, Explosion &out) override {
@@ -2016,20 +2041,13 @@ class AsyncCallEmission final : public CallEmission {
2016
2041
// argument buffer.
2017
2042
return ;
2018
2043
}
2019
- assert (call->arg_size () == 1 );
2020
- auto context = call->arg_begin ()->get ();
2021
2044
// Gather the values.
2022
2045
Explosion nativeExplosion;
2023
2046
auto layout = getAsyncContextLayout ();
2024
- auto dataAddr = layout.emitCastTo (IGF, context);
2025
2047
for (unsigned index = 0 , count = layout.getDirectReturnCount ();
2026
2048
index < count; ++index) {
2027
2049
auto fieldLayout = layout.getDirectReturnLayout (index);
2028
- Address fieldAddr =
2029
- fieldLayout.project (IGF, dataAddr, /* offsets*/ llvm::None);
2030
- auto &fieldTI = fieldLayout.getType ();
2031
- cast<LoadableTypeInfo>(fieldTI).loadAsTake (IGF, fieldAddr,
2032
- nativeExplosion);
2050
+ loadValue (fieldLayout, nativeExplosion);
2033
2051
}
2034
2052
2035
2053
out = nativeSchema.mapFromNative (IGF.IGM , IGF, nativeExplosion, resultType);
0 commit comments