{
GetFieldExpression (ec).EmitAssign (ec, source, leave_copy, false);
}
+
+ public void EmitAssignFromStack (EmitContext ec)
+ {
+ GetFieldExpression (ec).EmitAssignFromStack (ec);
+ }
}
public class HoistedParameter : HoistedVariable
ec.Emit (OpCodes.Dup);
no_value_label = ec.DefineLabel ();
ec.Emit (OpCodes.Brfalse_S, no_value_label);
+
+ if (Variable.HoistedVariant != null)
+ ec.EmitThis ();
+
expr_unwrap.Emit (ec);
} else {
+ if (Variable?.HoistedVariant != null)
+ ec.EmitThis ();
+
expr.Emit (ec);
// Only to make verifier happy
value_on_stack = false;
}
- //
- // It's ok to have variable builder created out of order. It simplifies emit
- // of statements like while (condition) { }
- //
- if (!Variable.Created)
- Variable.CreateBuilder (ec);
-
- Variable.EmitAssign (ec);
+ if (Variable.HoistedVariant != null) {
+ Variable.HoistedVariant.EmitAssignFromStack (ec);
- if (expr_unwrap != null) {
- ec.MarkLabel (no_value_label);
- } else if (!value_on_stack) {
- Variable.Emit (ec);
+ if (expr_unwrap != null) {
+ ec.MarkLabel (no_value_label);
+ } else if (!value_on_stack) {
+ Variable.HoistedVariant.Emit (ec);
+ }
+ } else {
+ //
+ // It's ok to have variable builder created out of order. It simplifies emit
+ // of statements like while (condition) { }
+ //
+ if (!Variable.Created)
+ Variable.CreateBuilder (ec);
+
+ Variable.EmitAssign (ec);
+
+ if (expr_unwrap != null) {
+ ec.MarkLabel (no_value_label);
+ } else if (!value_on_stack) {
+ Variable.Emit (ec);
+ }
}
}
}
--- /dev/null
+using System.Collections.Generic;
+
+class Expr
+{
+ public int Field;
+}
+
+static class X
+{
+ public static IEnumerable<int> Test (Expr expr)
+ {
+ object exprCur = expr;
+ if (exprCur is Expr list) {
+ yield return list.Field;
+ }
+ }
+
+ public static IEnumerable<string> Test2 (int? expr)
+ {
+ int? exprCur = expr;
+ while (exprCur != null) {
+ if (exprCur is int list) {
+ yield return list.ToString ();
+ }
+ }
+ }
+
+ public static void Main ()
+ {
+ Test (null);
+ Test2 (3);
+ }
+}
\ No newline at end of file
</method>
</type>
</test>
+ <test name="test-pattern-09.cs">
+ <type name="Expr">
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="X">
+ <method name="System.Collections.Generic.IEnumerable`1[System.Int32] Test(Expr)" attrs="150">
+ <size>30</size>
+ </method>
+ <method name="System.Collections.Generic.IEnumerable`1[System.String] Test2(System.Nullable`1[System.Int32])" attrs="150">
+ <size>30</size>
+ </method>
+ <method name="Void Main()" attrs="150">
+ <size>21</size>
+ </method>
+ </type>
+ <type name="X+<Test>c__Iterator0">
+ <method name="Boolean MoveNext()" attrs="486">
+ <size>124</size>
+ </method>
+ <method name="Int32 System.Collections.Generic.IEnumerator<int>.get_Current()" attrs="2529">
+ <size>14</size>
+ </method>
+ <method name="System.Object System.Collections.IEnumerator.get_Current()" attrs="2529">
+ <size>19</size>
+ </method>
+ <method name="Void Dispose()" attrs="486">
+ <size>15</size>
+ </method>
+ <method name="Void Reset()" attrs="486">
+ <size>6</size>
+ </method>
+ <method name="System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()" attrs="481">
+ <size>14</size>
+ </method>
+ <method name="System.Collections.Generic.IEnumerator`1[System.Int32] System.Collections.Generic.IEnumerable<int>.GetEnumerator()" attrs="481">
+ <size>40</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="X+<Test2>c__Iterator1">
+ <method name="Boolean MoveNext()" attrs="486">
+ <size>161</size>
+ </method>
+ <method name="System.String System.Collections.Generic.IEnumerator<string>.get_Current()" attrs="2529">
+ <size>14</size>
+ </method>
+ <method name="System.Object System.Collections.IEnumerator.get_Current()" attrs="2529">
+ <size>14</size>
+ </method>
+ <method name="Void Dispose()" attrs="486">
+ <size>15</size>
+ </method>
+ <method name="Void Reset()" attrs="486">
+ <size>6</size>
+ </method>
+ <method name="System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()" attrs="481">
+ <size>14</size>
+ </method>
+ <method name="System.Collections.Generic.IEnumerator`1[System.String] System.Collections.Generic.IEnumerable<string>.GetEnumerator()" attrs="481">
+ <size>40</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="test-pragma-unrecognized.cs">
<type name="C">
<method name="Void Main()" attrs="150">