//
public class ImplicitDelegateCreation : DelegateCreation
{
+ Field mg_cache;
+
public ImplicitDelegateCreation (TypeSpec delegateType, MethodGroupExpr mg, Location loc)
{
type = delegateType;
this.method_group = mg;
this.loc = loc;
}
+
+ //
+ // Returns true when type is MVAR or has MVAR reference
+ //
+ static bool ContainsMethodTypeParameter (TypeSpec type)
+ {
+ var tps = type as TypeParameterSpec;
+ if (tps != null)
+ return tps.IsMethodOwned;
+
+ var ec = type as ElementTypeSpec;
+ if (ec != null)
+ return ContainsMethodTypeParameter (ec.Element);
+
+ foreach (var t in type.TypeArguments) {
+ if (ContainsMethodTypeParameter (t)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected override Expression DoResolve (ResolveContext ec)
+ {
+ var expr = base.DoResolve (ec);
+ if (expr == null)
+ return null;
+
+ if (ec.IsInProbingMode)
+ return expr;
+
+ //
+ // Cache any static delegate creation
+ //
+ if (method_group.InstanceExpression != null)
+ return expr;
+
+ //
+ // Cannot easily cache types with MVAR
+ //
+ if (ContainsMethodTypeParameter (type))
+ return expr;
+
+ if (ContainsMethodTypeParameter (method_group.BestCandidate.DeclaringType))
+ return expr;
+
+ //
+ // Create type level cache for a delegate instance
+ //
+ var parent = ec.CurrentMemberDefinition.Parent.PartialContainer;
+ int id = parent.MethodGroupsCounter++;
+
+ mg_cache = new Field (parent, new TypeExpression (type, loc),
+ Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED,
+ new MemberName (CompilerGeneratedContainer.MakeName (null, "f", "mg$cache", id), loc), null);
+ mg_cache.Define ();
+ parent.AddField (mg_cache);
+
+ return expr;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ Label l_initialized = ec.DefineLabel ();
+
+ if (mg_cache != null) {
+ ec.Emit (OpCodes.Ldsfld, mg_cache.Spec);
+ ec.Emit (OpCodes.Brtrue_S, l_initialized);
+ }
+
+ base.Emit (ec);
+
+ if (mg_cache != null) {
+ ec.Emit (OpCodes.Stsfld, mg_cache.Spec);
+ ec.MarkLabel (l_initialized);
+ ec.Emit (OpCodes.Ldsfld, mg_cache.Spec);
+ }
+ }
}
//
<size>37</size>\r
</method>\r
<method name="Void InvokeTest()" attrs="129">\r
- <size>459</size>\r
+ <size>476</size>\r
</method>\r
<method name="Void InvokeMember()" attrs="129">\r
<size>907</size>\r
<size>2</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
- <size>175</size>\r
+ <size>192</size>\r
</method>\r
<method name="System.Object <Main>m__0(System.Object)" attrs="145">\r
<size>10</size>\r
<size>5</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>28</size>\r
+ <size>62</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>42</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
- <size>332</size>\r
+ <size>349</size>\r
</method>\r
<method name="Int32 Foo(Int32)" attrs="145">\r
<size>11</size>\r
<test name="gtest-161.cs">\r
<type name="App">\r
<method name="Void Main()" attrs="150">\r
- <size>57</size>\r
+ <size>74</size>\r
</method>\r
<method name="U apply[T,U](T, FP+Mapping`2[T,U])" attrs="145">\r
<size>16</size>\r
<size>8</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>51</size>\r
+ <size>68</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>2</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>19</size>\r
+ <size>36</size>\r
</method>\r
</type>\r
<type name="X+<Foo>c__AnonStorey0`1[T]">\r
<size>10</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
- <size>28</size>\r
+ <size>45</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>30</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>142</size>\r
+ <size>210</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<test name="gtest-334.cs">\r
<type name="Test">\r
<method name="Int32 Main()" attrs="150">\r
- <size>128</size>\r
+ <size>179</size>\r
</method>\r
<method name="Void DelegateMethod(Boolean)" attrs="145">\r
<size>2</size>\r
<size>2</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
- <size>172</size>\r
+ <size>189</size>\r
</method>\r
<method name="Void Method(Thing+Handler, System.String[])" attrs="150">\r
<size>2</size>\r
<size>2</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
- <size>228</size>\r
+ <size>245</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>10</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>25</size>\r
+ <size>42</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>68</size>\r
</method>\r
<method name="System.Action`1[System.Int32] Test_15(System.Action`1[System.Int32])" attrs="129">\r
- <size>29</size>\r
+ <size>46</size>\r
</method>\r
<method name="Void Helper[T](T)" attrs="145">\r
<size>2</size>\r
<size>31</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
- <size>27</size>\r
+ <size>44</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>2</size>\r
</method>\r
<method name="Void Bug()" attrs="134">\r
- <size>20</size>\r
+ <size>37</size>\r
</method>\r
<method name="Void Handler(System.Object, System.EventArgs)" attrs="150">\r
<size>2</size>\r
</type>\r
<type name="TestBug.MainClass">\r
<method name="Void Main()" attrs="150">\r
- <size>26</size>\r
+ <size>43</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>2</size>\r
</method>\r
<method name="Void Main(System.String[])" attrs="150">\r
- <size>101</size>\r
+ <size>169</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>16</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
- <size>91</size>\r
+ <size>125</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>17</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>30</size>\r
+ <size>47</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>18</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>27</size>\r
+ <size>44</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>98</size>\r
</method>\r
<method name="Void ConvertTest_10()" attrs="129">\r
- <size>164</size>\r
+ <size>181</size>\r
</method>\r
<method name="Void ConvertTest_11()" attrs="129">\r
<size>102</size>\r
<size>313</size>\r
</method>\r
<method name="Void EqualTestDelegate_3()" attrs="129">\r
- <size>213</size>\r
+ <size>230</size>\r
</method>\r
<method name="Void ExclusiveOrTest()" attrs="129">\r
<size>116</size>\r
<size>2</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
- <size>243</size>\r
+ <size>294</size>\r
</method>\r
<method name="IEnumerable`1 <Main>m__0(IEnumerable)" attrs="145">\r
<size>7</size>\r
<size>2</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>20</size>\r
+ <size>37</size>\r
</method>\r
<method name="Void .ctor(Foo)" attrs="6278">\r
<size>8</size>\r
<size>15</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>114</size>\r
+ <size>165</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>31</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>129</size>\r
+ <size>180</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>56</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>72</size>\r
+ <size>89</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>7</size>\r
</method>\r
<method name="Void .cctor()" attrs="6289">\r
- <size>24</size>\r
+ <size>41</size>\r
</method>\r
</type>\r
</test>\r
<size>32</size>\r
</method>\r
<method name="Void <Main>m__0()" attrs="145">\r
- <size>19</size>\r
+ <size>36</size>\r
</method>\r
</type>\r
</test>\r
<size>10</size>\r
</method>\r
<method name="Void X()" attrs="134">\r
- <size>20</size>\r
+ <size>37</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<test name="test-708.cs">\r
<type name="A">\r
<method name="A+ADelegate Delegate2(Boolean)" attrs="150">\r
- <size>33</size>\r
+ <size>50</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
<size>2</size>\r
<size>10</size>\r
</method>\r
<method name="Int32 GetPhones()" attrs="129">\r
- <size>30</size>\r
+ <size>47</size>\r
</method>\r
<method name="Int32 Main()" attrs="150">\r
<size>36</size>\r
<size>38</size>\r
</method>\r
<method name="Void StaticCallback()" attrs="134">\r
- <size>32</size>\r
+ <size>49</size>\r
</method>\r
<method name="Void StaticCallback(System.String)" attrs="150">\r
<size>36</size>\r
<size>2</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>32</size>\r
+ <size>66</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r
<size>12</size>\r
</method>\r
<method name="Void Main()" attrs="150">\r
- <size>40</size>\r
+ <size>57</size>\r
</method>\r
<method name="Void .ctor()" attrs="6278">\r
<size>7</size>\r