@@ -81,10 +81,6 @@ struct ArgumentDecoderInfo {
81
81
// / The type of `decodeNextArgument` method.
82
82
CanSILFunctionType MethodType;
83
83
84
- // / Protocol requirements associated with the generic
85
- // / parameter `Argument` of this decode method.
86
- GenericSignature::RequiredProtocols ProtocolRequirements;
87
-
88
84
// Witness metadata for conformance to DistributedTargetInvocationDecoder
89
85
// protocol.
90
86
WitnessMetadata Witness;
@@ -94,31 +90,19 @@ struct ArgumentDecoderInfo {
94
90
FunctionPointer decodeNextArgumentPtr,
95
91
CanSILFunctionType decodeNextArgumentTy)
96
92
: Decoder(decoder), MethodPtr(decodeNextArgumentPtr),
97
- MethodType (decodeNextArgumentTy),
98
- ProtocolRequirements(findProtocolRequirements(decodeNextArgumentTy)) {
93
+ MethodType (decodeNextArgumentTy) {
99
94
Witness.SelfMetadata = decoderType;
100
95
Witness.SelfWitnessTable = decoderWitnessTable;
101
96
}
102
97
103
98
CanSILFunctionType getMethodType () const { return MethodType; }
104
99
105
- ArrayRef<ProtocolDecl *> getProtocolRequirements () const {
106
- return ProtocolRequirements ;
100
+ WitnessMetadata * getWitnessMetadata () const {
101
+ return const_cast <WitnessMetadata *>(&Witness) ;
107
102
}
108
103
109
104
// / Form a callee to a decode method - `decodeNextArgument`.
110
105
Callee getCallee () const ;
111
-
112
- private:
113
- static GenericSignature::RequiredProtocols
114
- findProtocolRequirements (CanSILFunctionType decodeMethodTy) {
115
- auto signature = decodeMethodTy->getInvocationGenericSignature ();
116
- auto genericParams = signature.getGenericParams ();
117
-
118
- // func decodeNextArgument<Arg : #SerializationRequirement#>() throws -> Arg
119
- assert (genericParams.size () == 1 );
120
- return signature->getRequiredProtocols (genericParams.front ());
121
- }
122
106
};
123
107
124
108
class DistributedAccessor {
@@ -156,10 +140,6 @@ class DistributedAccessor {
156
140
llvm::Value *argumentType, const SILParameterInfo ¶m,
157
141
Explosion &arguments);
158
142
159
- void lookupWitnessTables (llvm::Value *value,
160
- ArrayRef<ProtocolDecl *> protocols,
161
- Explosion &witnessTables);
162
-
163
143
// / Load witness table addresses (if any) from the given buffer
164
144
// / into the given argument explosion.
165
145
// /
@@ -417,17 +397,13 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
417
397
// substitution Argument -> <argument metadata>
418
398
decodeArgs.add (argumentType);
419
399
420
- // Lookup witness tables for the requirement on the argument type.
421
- lookupWitnessTables (argumentType, decoder.getProtocolRequirements (),
422
- decodeArgs);
423
-
424
400
Address calleeErrorSlot;
425
401
llvm::Value *decodeError = nullptr ;
426
402
427
403
emission->begin ();
428
404
{
429
405
emission->setArgs (decodeArgs, /* isOutlined=*/ false ,
430
- /* witnessMetadata=*/ nullptr );
406
+ /* witnessMetadata=*/ decoder. getWitnessMetadata () );
431
407
432
408
Explosion result;
433
409
emission->emitToExplosion (result, /* isOutlined=*/ false );
@@ -528,37 +504,6 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
528
504
}
529
505
}
530
506
531
- void DistributedAccessor::lookupWitnessTables (
532
- llvm::Value *value, ArrayRef<ProtocolDecl *> protocols,
533
- Explosion &witnessTables) {
534
- auto conformsToProtocol = IGM.getConformsToProtocolFunctionPointer ();
535
-
536
- for (auto *protocol : protocols) {
537
- auto *protocolDescriptor = IGM.getAddrOfProtocolDescriptor (protocol);
538
- auto *witnessTable =
539
- IGF.Builder .CreateCall (conformsToProtocol, {value, protocolDescriptor});
540
-
541
- auto failBB = IGF.createBasicBlock (" missing-witness" );
542
- auto contBB = IGF.createBasicBlock (" " );
543
-
544
- auto isNull = IGF.Builder .CreateICmpEQ (
545
- witnessTable, llvm::ConstantPointerNull::get (IGM.WitnessTablePtrTy ));
546
- IGF.Builder .CreateCondBr (isNull, failBB, contBB);
547
-
548
- // This operation shouldn't fail because runtime should have checked that
549
- // a particular argument type conforms to `SerializationRequirement`
550
- // of the distributed actor the decoder is used for. If it does fail
551
- // then accessor should trap.
552
- {
553
- IGF.Builder .emitBlock (failBB);
554
- IGF.emitTrap (" missing witness table" , /* EmitUnreachable=*/ true );
555
- }
556
-
557
- IGF.Builder .emitBlock (contBB);
558
- witnessTables.add (witnessTable);
559
- }
560
- }
561
-
562
507
void DistributedAccessor::emitLoadOfWitnessTables (llvm::Value *witnessTables,
563
508
llvm::Value *numTables,
564
509
unsigned expectedWitnessTables,
@@ -803,70 +748,22 @@ DistributedAccessor::getCalleeForDistributedTarget(llvm::Value *self) const {
803
748
804
749
ArgumentDecoderInfo DistributedAccessor::findArgumentDecoder (
805
750
llvm::Value *decoder, llvm::Value *decoderTy, llvm::Value *witnessTable) {
806
- auto *actor = getDistributedActorOf (Target);
807
- auto expansionContext = IGM.getMaximalTypeExpansionContext ();
808
-
809
- auto *decodeFn = IGM.Context .getDistributedActorArgumentDecodingMethod (actor);
810
- assert (decodeFn && " no suitable decoder?" );
811
-
812
- auto methodTy = IGM.getSILTypes ().getConstantFunctionType (
813
- expansionContext, SILDeclRef (decodeFn));
814
-
815
- auto fpKind = FunctionPointerKind::defaultAsync ();
816
- auto signature = IGM.getSignature (methodTy, fpKind);
817
-
818
- // If the decoder class is `final`, let's emit a direct reference.
819
- auto *decoderDecl = decodeFn->getDeclContext ()->getSelfNominalTypeDecl ();
820
-
821
- // If decoder is a class, need to load it first because generic parameter
822
- // is passed indirectly. This is good for structs and enums because
823
- // `decodeNextArgument` is a mutating method, but not for classes because
824
- // in that case heap object is mutated directly.
825
- bool usesDispatchThunk = false ;
751
+ auto &C = IGM.Context ;
826
752
827
- if ( auto classDecl = dyn_cast<ClassDecl>(decoderDecl)) {
828
- auto selfTy = methodTy-> getSelfParameter (). getSILStorageType (
829
- IGM. getSILModule (), methodTy, expansionContext );
753
+ auto decoderProtocol = C. getDistributedTargetInvocationDecoderDecl ();
754
+ SILDeclRef decodeNextArgumentRef (
755
+ decoderProtocol-> getSingleRequirement (C. Id_decodeNextArgument ) );
830
756
831
- auto &classTI = IGM.getTypeInfo (selfTy).as <ClassTypeInfo>();
832
- auto &classLayout = classTI.getClassLayout (IGM, selfTy,
833
- /* forBackwardDeployment=*/ false );
757
+ llvm::Constant *fnPtr =
758
+ IGM.getAddrOfDispatchThunk (decodeNextArgumentRef, NotForDefinition);
834
759
835
- llvm::Value *typedDecoderPtr = IGF.Builder .CreateBitCast (
836
- decoder, classLayout.getType ()->getPointerTo ()->getPointerTo ());
837
-
838
- Explosion instance;
839
-
840
- classTI.loadAsTake (IGF,
841
- {typedDecoderPtr, classTI.getStorageType (),
842
- classTI.getBestKnownAlignment ()},
843
- instance);
844
-
845
- decoder = instance.claimNext ();
846
-
847
- // / When using library evolution functions have another "dispatch thunk"
848
- // / so we must use this instead of the decodeFn directly.
849
- usesDispatchThunk =
850
- getMethodDispatch (decodeFn) == swift::MethodDispatch::Class &&
851
- classDecl->hasResilientMetadata ();
852
- }
853
-
854
- FunctionPointer methodPtr;
855
-
856
- if (usesDispatchThunk) {
857
- auto fnPtr = IGM.getAddrOfDispatchThunk (SILDeclRef (decodeFn), NotForDefinition);
858
- methodPtr = FunctionPointer::createUnsigned (
859
- methodTy, fnPtr, signature, /* useSignature=*/ true );
860
- } else {
861
- SILFunction *decodeSILFn = IGM.getSILModule ().lookUpFunction (SILDeclRef (decodeFn));
862
- auto fnPtr = IGM.getAddrOfSILFunction (decodeSILFn, NotForDefinition,
863
- /* isDynamicallyReplaceable=*/ false );
864
- methodPtr = FunctionPointer::forDirect (
865
- classifyFunctionPointerKind (decodeSILFn), fnPtr,
866
- /* secondaryValue=*/ nullptr , signature);
867
- }
760
+ auto fnType = IGM.getSILTypes ().getConstantFunctionType (
761
+ IGM.getMaximalTypeExpansionContext (), decodeNextArgumentRef);
868
762
869
- return {decoder, decoderTy, witnessTable, methodPtr, methodTy};
763
+ auto sig = IGM.getSignature (fnType);
764
+ auto fn = FunctionPointer::forDirect (fnType, fnPtr,
765
+ /* secondaryValue=*/ nullptr , sig, true );
766
+ return {decoder, decoderTy, witnessTable, fn, fnType};
870
767
}
871
768
872
769
SILType DistributedAccessor::getResultType () const {
0 commit comments