@@ -64,6 +64,12 @@ llvm::Value *irgen::emitDistributedActorInitializeRemote(
6464
6565namespace {
6666
67+ struct AllocationInfo {
68+ SILType Type;
69+ const TypeInfo &TI;
70+ StackAddress Addr;
71+ };
72+
6773class DistributedAccessor {
6874 IRGenModule &IGM;
6975 IRGenFunction &IGF;
@@ -76,6 +82,9 @@ class DistributedAccessor {
7682 // / The asynchronous context associated with this accessor.
7783 AsyncContextLayout AsyncLayout;
7884
85+ // / The list of all arguments that were allocated on the stack.
86+ SmallVector<AllocationInfo, 4 > AllocatedArguments;
87+
7988public:
8089 DistributedAccessor (IRGenFunction &IGF, SILFunction *method,
8190 CanSILFunctionType accessorTy);
@@ -203,28 +212,56 @@ void DistributedAccessor::computeArguments(llvm::Value *argumentBuffer,
203212 // 3. Adjust typed pointer to the alignement of the type.
204213 auto alignedOffset = typeInfo.roundUpToTypeAlignment (IGF, eltPtr, paramTy);
205214
206- // 4. Create an exploded version of the type to pass as an
207- // argument to distributed method.
208-
209215 if (paramTy.isObject ()) {
210216 auto &nativeSchema = typeInfo.nativeParameterValueSchema (IGM);
211-
212- if (nativeSchema.requiresIndirect ()) {
213- llvm_unreachable (" indirect parameters are not supported" );
214- }
215-
216217 // If schema is empty, skip to the next argument.
217218 if (nativeSchema.empty ())
218219 continue ;
220+ }
221+
222+ // 4. Create an exploded version of the type to pass as an
223+ // argument to distributed method.
224+
225+ switch (param.getConvention ()) {
226+ case ParameterConvention::Indirect_In:
227+ case ParameterConvention::Indirect_In_Constant: {
228+ // The +1 argument is passed indirectly, so we need to copy it into
229+ // a temporary.
219230
220- // 5. Load argument value from the element pointer.
221- cast<LoadableTypeInfo>(typeInfo).loadAsCopy (IGF, alignedOffset, arguments);
222- } else {
223- // If the value is not loadable e.g. generic or resilient
224- // pass its address as an argument.
225- //
226- // TODO: This needs to be copied and destroyed.
231+ auto stackAddr = typeInfo.allocateStack (IGF, paramTy, " arg.temp" );
232+ auto argPtr = stackAddr.getAddress ().getAddress ();
233+
234+ typeInfo.initializeWithCopy (IGF, stackAddr.getAddress (), alignedOffset,
235+ paramTy, /* isOutlined=*/ false );
236+ arguments.add (argPtr);
237+
238+ // Remember to deallocate later.
239+ AllocatedArguments.push_back ({paramTy, typeInfo, stackAddr});
240+ break ;
241+ }
242+
243+ case ParameterConvention::Indirect_In_Guaranteed: {
244+ // The argument is +0, so we can use the address of the param in
245+ // the context directly.
227246 arguments.add (alignedOffset.getAddress ());
247+ break ;
248+ }
249+
250+ case ParameterConvention::Indirect_Inout:
251+ case ParameterConvention::Indirect_InoutAliasable:
252+ llvm_unreachable (" indirect parameters are not supported" );
253+
254+ case ParameterConvention::Direct_Guaranteed:
255+ case ParameterConvention::Direct_Unowned: {
256+ cast<LoadableTypeInfo>(typeInfo).loadAsTake (IGF, alignedOffset,
257+ arguments);
258+ break ;
259+ }
260+
261+ case ParameterConvention::Direct_Owned:
262+ // Copy the value out at +1.
263+ cast<LoadableTypeInfo>(typeInfo).loadAsCopy (IGF, alignedOffset,
264+ arguments);
228265 }
229266
230267 // 6. Move the offset to the beginning of the next element, unless
@@ -335,6 +372,12 @@ void DistributedAccessor::emit() {
335372
336373 emission->end ();
337374
375+ // Deallocate all of the copied arguments.
376+ {
377+ for (auto &entry : AllocatedArguments)
378+ entry.TI .deallocateStack (IGF, entry.Addr , entry.Type );
379+ }
380+
338381 Explosion voidResult;
339382 emitAsyncReturn (IGF, AsyncLayout,
340383 accessorConv.getSILResultType (expansionContext),
0 commit comments