@@ -81,10 +81,6 @@ struct ArgumentDecoderInfo {
8181 // / The type of `decodeNextArgument` method.
8282 CanSILFunctionType MethodType;
8383
84- // / Protocol requirements associated with the generic
85- // / parameter `Argument` of this decode method.
86- GenericSignature::RequiredProtocols ProtocolRequirements;
87-
8884 // Witness metadata for conformance to DistributedTargetInvocationDecoder
8985 // protocol.
9086 WitnessMetadata Witness;
@@ -94,31 +90,19 @@ struct ArgumentDecoderInfo {
9490 FunctionPointer decodeNextArgumentPtr,
9591 CanSILFunctionType decodeNextArgumentTy)
9692 : Decoder(decoder), MethodPtr(decodeNextArgumentPtr),
97- MethodType (decodeNextArgumentTy),
98- ProtocolRequirements(findProtocolRequirements(decodeNextArgumentTy)) {
93+ MethodType (decodeNextArgumentTy) {
9994 Witness.SelfMetadata = decoderType;
10095 Witness.SelfWitnessTable = decoderWitnessTable;
10196 }
10297
10398 CanSILFunctionType getMethodType () const { return MethodType; }
10499
105- ArrayRef<ProtocolDecl *> getProtocolRequirements () const {
106- return ProtocolRequirements ;
100+ WitnessMetadata * getWitnessMetadata () const {
101+ return const_cast <WitnessMetadata *>(&Witness) ;
107102 }
108103
109104 // / Form a callee to a decode method - `decodeNextArgument`.
110105 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- }
122106};
123107
124108class DistributedAccessor {
@@ -156,10 +140,6 @@ class DistributedAccessor {
156140 llvm::Value *argumentType, const SILParameterInfo ¶m,
157141 Explosion &arguments);
158142
159- void lookupWitnessTables (llvm::Value *value,
160- ArrayRef<ProtocolDecl *> protocols,
161- Explosion &witnessTables);
162-
163143 // / Load witness table addresses (if any) from the given buffer
164144 // / into the given argument explosion.
165145 // /
@@ -417,17 +397,13 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
417397 // substitution Argument -> <argument metadata>
418398 decodeArgs.add (argumentType);
419399
420- // Lookup witness tables for the requirement on the argument type.
421- lookupWitnessTables (argumentType, decoder.getProtocolRequirements (),
422- decodeArgs);
423-
424400 Address calleeErrorSlot;
425401 llvm::Value *decodeError = nullptr ;
426402
427403 emission->begin ();
428404 {
429405 emission->setArgs (decodeArgs, /* isOutlined=*/ false ,
430- /* witnessMetadata=*/ nullptr );
406+ /* witnessMetadata=*/ decoder. getWitnessMetadata () );
431407
432408 Explosion result;
433409 emission->emitToExplosion (result, /* isOutlined=*/ false );
@@ -528,37 +504,6 @@ void DistributedAccessor::decodeArgument(unsigned argumentIdx,
528504 }
529505}
530506
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-
562507void DistributedAccessor::emitLoadOfWitnessTables (llvm::Value *witnessTables,
563508 llvm::Value *numTables,
564509 unsigned expectedWitnessTables,
@@ -803,70 +748,22 @@ DistributedAccessor::getCalleeForDistributedTarget(llvm::Value *self) const {
803748
804749ArgumentDecoderInfo DistributedAccessor::findArgumentDecoder (
805750 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 ;
826752
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 ) );
830756
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);
834759
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);
868762
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};
870767}
871768
872769SILType DistributedAccessor::getResultType () const {
0 commit comments