@@ -181,6 +181,28 @@ AsyncContextLayout irgen::getAsyncContextLayout(
181181 paramInfos.push_back ({ty, parameter.getConvention ()});
182182 }
183183
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+
184206 // ResultTypes directResults...;
185207 auto directResults = fnConv.getDirectSILResults ();
186208 for (auto result : directResults) {
@@ -192,20 +214,20 @@ AsyncContextLayout irgen::getAsyncContextLayout(
192214 directReturnInfos.push_back (result);
193215 }
194216
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);
200222}
201223
202224AsyncContextLayout::AsyncContextLayout (
203225 IRGenModule &IGM, LayoutStrategy strategy, ArrayRef<SILType> fieldTypes,
204226 ArrayRef<const TypeInfo *> fieldTypeInfos, IRGenFunction &IGF,
205227 CanSILFunctionType originalType, CanSILFunctionType substitutedType,
206228 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,
209231 ArrayRef<SILResultInfo> indirectReturnInfos,
210232 ArrayRef<SILResultInfo> directReturnInfos,
211233 Optional<AsyncContextLayout::ArgumentInfo> localContextInfo)
@@ -218,6 +240,7 @@ AsyncContextLayout::AsyncContextLayout(
218240 indirectReturnInfos(indirectReturnInfos.begin(),
219241 indirectReturnInfos.end()),
220242 localContextInfo(localContextInfo), bindings(std::move(bindings)),
243+ trailingWitnessInfo(trailingWitnessInfo),
221244 argumentInfos(argumentInfos.begin(), argumentInfos.end()) {
222245#ifndef NDEBUG
223246 assert (fieldTypeInfos.size () == fieldTypes.size () &&
@@ -1929,6 +1952,17 @@ class AsyncCallEmission final : public CallEmission {
19291952 getCallee ().getSubstitutions ());
19301953 }
19311954
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+
19321966public:
19331967 AsyncCallEmission (IRGenFunction &IGF, llvm::Value *selfValue, Callee &&callee)
19341968 : CallEmission(IGF, selfValue, std::move(callee)) {
@@ -1974,21 +2008,15 @@ class AsyncCallEmission final : public CallEmission {
19742008 llArgs.add (selfValue);
19752009 }
19762010 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- }
19852011 for (unsigned index = 0 , count = layout.getIndirectReturnCount ();
19862012 index < count; ++index) {
19872013 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);
19922020 }
19932021 if (layout.hasBindings ()) {
19942022 auto bindingLayout = layout.getBindingsLayout ();
@@ -1997,10 +2025,7 @@ class AsyncCallEmission final : public CallEmission {
19972025 }
19982026 if (selfValue) {
19992027 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);
20042029 }
20052030 }
20062031 void emitCallToUnmappedExplosion (llvm::CallInst *call, Explosion &out) override {
@@ -2016,20 +2041,13 @@ class AsyncCallEmission final : public CallEmission {
20162041 // argument buffer.
20172042 return ;
20182043 }
2019- assert (call->arg_size () == 1 );
2020- auto context = call->arg_begin ()->get ();
20212044 // Gather the values.
20222045 Explosion nativeExplosion;
20232046 auto layout = getAsyncContextLayout ();
2024- auto dataAddr = layout.emitCastTo (IGF, context);
20252047 for (unsigned index = 0 , count = layout.getDirectReturnCount ();
20262048 index < count; ++index) {
20272049 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);
20332051 }
20342052
20352053 out = nativeSchema.mapFromNative (IGF.IGM , IGF, nativeExplosion, resultType);
0 commit comments