17
17
#include " RValue.h"
18
18
#include " Scope.h"
19
19
#include " swift/AST/AST.h"
20
+ #include " swift/AST/Mangle.h"
20
21
#include " swift/SIL/SILArgument.h"
22
+ #include " swift/SIL/SILUndef.h"
21
23
#include " swift/SIL/TypeLowering.h"
22
24
#include " swift/Basic/Defer.h"
23
25
24
26
using namespace swift ;
25
27
using namespace Lowering ;
28
+ using namespace Mangle ;
26
29
27
30
static SILValue emitConstructorMetatypeArg (SILGenFunction &gen,
28
31
ValueDecl *ctor) {
@@ -692,6 +695,32 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
692
695
}
693
696
}
694
697
698
+ static ManagedValue emitSelfForMemberInit (SILGenFunction &SGF, SILLocation loc,
699
+ VarDecl *selfDecl) {
700
+ CanType selfFormalType = selfDecl->getType ()
701
+ ->getInOutObjectType ()->getCanonicalType ();
702
+ if (selfFormalType->hasReferenceSemantics ())
703
+ return SGF.emitRValueForDecl (loc, selfDecl, selfDecl->getType (),
704
+ AccessSemantics::DirectToStorage,
705
+ SGFContext::AllowImmediatePlusZero)
706
+ .getAsSingleValue (SGF, loc);
707
+ else
708
+ return SGF.emitLValueForDecl (loc, selfDecl,
709
+ selfDecl->getType ()->getCanonicalType (),
710
+ AccessKind::Write,
711
+ AccessSemantics::DirectToStorage);
712
+ }
713
+
714
+ static LValue emitLValueForMemberInit (SILGenFunction &SGF, SILLocation loc,
715
+ VarDecl *selfDecl,
716
+ VarDecl *property) {
717
+ CanType selfFormalType = selfDecl->getType ()
718
+ ->getInOutObjectType ()->getCanonicalType ();
719
+ auto self = emitSelfForMemberInit (SGF, loc, selfDecl);
720
+ return SGF.emitPropertyLValue (loc, self, selfFormalType, property,
721
+ AccessKind::Write,
722
+ AccessSemantics::DirectToStorage);
723
+ }
695
724
696
725
// / Emit a member initialization for the members described in the
697
726
// / given pattern from the given source value.
@@ -720,28 +749,11 @@ static void emitMemberInit(SILGenFunction &SGF, VarDecl *selfDecl,
720
749
auto named = cast<NamedPattern>(pattern);
721
750
// Form the lvalue referencing this member.
722
751
WritebackScope scope (SGF);
723
- SILLocation loc = pattern;
724
- ManagedValue self;
725
- CanType selfFormalType = selfDecl->getType ()
726
- ->getInOutObjectType ()->getCanonicalType ();
727
- if (selfFormalType->hasReferenceSemantics ())
728
- self = SGF.emitRValueForDecl (loc, selfDecl, selfDecl->getType (),
729
- AccessSemantics::DirectToStorage,
730
- SGFContext::AllowImmediatePlusZero)
731
- .getAsSingleValue (SGF, loc);
732
- else
733
- self = SGF.emitLValueForDecl (loc, selfDecl,
734
- src.getType ()->getCanonicalType (),
735
- AccessKind::Write,
736
- AccessSemantics::DirectToStorage);
737
-
738
- LValue memberRef =
739
- SGF.emitPropertyLValue (loc, self, selfFormalType, named->getDecl (),
740
- AccessKind::Write,
741
- AccessSemantics::DirectToStorage);
752
+ LValue memberRef = emitLValueForMemberInit (SGF, pattern, selfDecl,
753
+ named->getDecl ());
742
754
743
755
// Assign to it.
744
- SGF.emitAssignToLValue (loc , std::move (src), std::move (memberRef));
756
+ SGF.emitAssignToLValue (pattern , std::move (src), std::move (memberRef));
745
757
return ;
746
758
}
747
759
@@ -765,20 +777,117 @@ static void emitMemberInit(SILGenFunction &SGF, VarDecl *selfDecl,
765
777
}
766
778
}
767
779
780
+ static SILValue getBehaviorInitStorageFn (SILGenFunction &gen,
781
+ VarDecl *behaviorVar) {
782
+ std::string behaviorInitName;
783
+ {
784
+ Mangler m;
785
+ m.mangleBehaviorInitThunk (behaviorVar);
786
+ behaviorInitName = m.finalize ();
787
+ }
788
+
789
+ SILFunction *thunkFn;
790
+ // Skip out early if we already emitted this thunk.
791
+ if (auto existing = gen.SGM .M .lookUpFunction (behaviorInitName)) {
792
+ thunkFn = existing;
793
+ } else {
794
+ auto init = behaviorVar->getBehavior ()->InitStorageDecl .getDecl ();
795
+ auto initFn = gen.SGM .getFunction (SILDeclRef (init), NotForDefinition);
796
+
797
+ // Emit a thunk to inject the `self` metatype and implode tuples.
798
+ auto storageVar = behaviorVar->getBehavior ()->StorageDecl ;
799
+ auto selfTy = behaviorVar->getDeclContext ()->getDeclaredInterfaceType ();
800
+ auto initTy = gen.getLoweredType (selfTy).getFieldType (behaviorVar,
801
+ gen.SGM .M );
802
+ auto storageTy = gen.getLoweredType (selfTy).getFieldType (storageVar,
803
+ gen.SGM .M );
804
+
805
+ auto initConstantTy = initFn->getLoweredType ().castTo <SILFunctionType>();
806
+
807
+ auto param = SILParameterInfo (initTy.getSwiftRValueType (),
808
+ initTy.isAddress () ? ParameterConvention::Indirect_In
809
+ : ParameterConvention::Direct_Owned);
810
+ auto result = SILResultInfo (storageTy.getSwiftRValueType (),
811
+ storageTy.isAddress () ? ResultConvention::Indirect
812
+ : ResultConvention::Owned);
813
+
814
+ initConstantTy = SILFunctionType::get (initConstantTy->getGenericSignature (),
815
+ initConstantTy->getExtInfo (),
816
+ ParameterConvention::Direct_Unowned,
817
+ param,
818
+ result,
819
+ // TODO: throwing initializer?
820
+ None,
821
+ gen.getASTContext ());
822
+
823
+ // TODO: Generate the body of the thunk.
824
+ thunkFn = gen.SGM .M .getOrCreateFunction (SILLocation (behaviorVar),
825
+ behaviorInitName,
826
+ SILLinkage::PrivateExternal,
827
+ initConstantTy,
828
+ IsBare, IsTransparent, IsFragile);
829
+
830
+
831
+ }
832
+ return gen.B .createFunctionRef (behaviorVar, thunkFn);
833
+ }
834
+
835
+ static SILValue getBehaviorSetterFn (SILGenFunction &gen, VarDecl *behaviorVar) {
836
+ auto set = behaviorVar->getSetter ();
837
+ auto setFn = gen.SGM .getFunction (SILDeclRef (set), NotForDefinition);
838
+
839
+ // TODO: The setter may need to be a thunk, to implode tuples or perform
840
+ // reabstractions.
841
+ return gen.B .createFunctionRef (behaviorVar, setFn);
842
+ }
843
+
768
844
void SILGenFunction::emitMemberInitializers (VarDecl *selfDecl,
769
845
NominalTypeDecl *nominal) {
770
846
for (auto member : nominal->getMembers ()) {
771
- // Find pattern binding declarations that have initializers.
772
- auto pbd = dyn_cast<PatternBindingDecl>(member);
773
- if (!pbd || pbd->isStatic ()) continue ;
847
+ // Find instance pattern binding declarations that have initializers.
848
+ if ( auto pbd = dyn_cast<PatternBindingDecl>(member)) {
849
+ if ( pbd->isStatic ()) continue ;
774
850
775
- for (auto entry : pbd->getPatternList ()) {
776
- auto init = entry.getInit ();
777
- if (!init) continue ;
851
+ for (auto entry : pbd->getPatternList ()) {
852
+ auto init = entry.getInit ();
853
+ if (!init) continue ;
778
854
779
- // Cleanup after this initialization.
780
- FullExpr scope (Cleanups, entry.getPattern ());
781
- emitMemberInit (*this , selfDecl, entry.getPattern (), emitRValue (init));
855
+ // Cleanup after this initialization.
856
+ FullExpr scope (Cleanups, entry.getPattern ());
857
+ emitMemberInit (*this , selfDecl, entry.getPattern (), emitRValue (init));
858
+ }
859
+ }
860
+
861
+ // Introduce behavior initialization markers for properties that need them.
862
+ if (auto var = dyn_cast<VarDecl>(member)) {
863
+ if (var->isStatic ()) continue ;
864
+ if (!var->hasBehaviorNeedingInitialization ()) continue ;
865
+
866
+ // Get the initializer method for behavior.
867
+ auto init = var->getBehavior ()->InitStorageDecl ;
868
+ SILValue initFn = getBehaviorInitStorageFn (*this , var);
869
+
870
+ // Get the behavior's storage we need to initialize.
871
+ auto storage = var->getBehavior ()->StorageDecl ;
872
+ LValue storageRef = emitLValueForMemberInit (*this , var, selfDecl,storage);
873
+ // Shed any reabstraction over the member.
874
+ while (storageRef.isLastComponentTranslation ())
875
+ storageRef.dropLastTranslationComponent ();
876
+
877
+ auto storageAddr = emitAddressOfLValue (var, std::move (storageRef),
878
+ AccessKind::ReadWrite);
879
+
880
+ // Get the setter.
881
+ auto setterFn = getBehaviorSetterFn (*this , var);
882
+ auto self = emitSelfForMemberInit (*this , var, selfDecl);
883
+
884
+ auto mark = B.createMarkUninitializedBehavior (var,
885
+ initFn, init.getSubstitutions (), storageAddr.getValue (),
886
+ setterFn, getForwardingSubstitutions (), self.getValue (),
887
+ getLoweredType (var->getType ()).getAddressType ());
888
+
889
+ // The mark instruction stands in for the behavior property.
890
+ VarLocs[var].value = mark;
782
891
}
783
892
}
784
893
}
0 commit comments