}
OpCode call_op;
+ LocalTemporary lt = null;
if (method.IsStatic) {
call_op = OpCodes.Call;
if (DuplicateArguments) {
ec.Emit (OpCodes.Dup);
if (Arguments != null && Arguments.Count != 0) {
- var lt = new LocalTemporary (instance_on_stack_type);
+ lt = new LocalTemporary (instance_on_stack_type);
lt.Store (ec);
instance_copy = lt;
}
if (instance_copy != null) {
EmitCallInstance (ec, instance_copy, method.DeclaringType, call_op);
- var lt = instance_copy as LocalTemporary;
if (lt != null)
lt.Release (ec);
}
return null;
}
+ public override bool ContainsEmitWithAwait ()
+ {
+ return arguments != null && arguments.ContainsEmitWithAwait ();
+ }
+
//
// Checks whether the type is an interface that has the
// [ComImport, CoClass] attributes and must be treated
} else if (vr != null && vr.IsRef) {
vr.EmitLoad (ec);
}
-
- if (arguments != null)
+
+ if (arguments != null) {
+ if ((arguments.Count > (this is NewInitialize ? 0 : 1)) && arguments.ContainsEmitWithAwait ())
+ arguments = arguments.Emit (ec, false, true);
+
arguments.Emit (ec);
+ }
if (is_value_type) {
if (method == null) {
}
}
- public void EmitNew (EmitContext ec, New source, bool leave_copy)
- {
- if (!source.Emit (ec, this)) {
- if (leave_copy)
- throw new NotImplementedException ();
-
- return;
- }
-
- throw new NotImplementedException ();
- }
-
public override Expression EmitToField (EmitContext ec)
{
//
t.initializers.Add (e.Clone (clonectx));
}
+ public override bool ContainsEmitWithAwait ()
+ {
+ foreach (var e in initializers) {
+ if (e.ContainsEmitWithAwait ())
+ return true;
+ }
+
+ return false;
+ }
+
public override Expression CreateExpressionTree (ResolveContext ec)
{
var expr_initializers = new ArrayInitializer (initializers.Count, loc);
e.Emit (ec);
}
+ public override Expression EmitToField (EmitContext ec)
+ {
+ return (Expression) new_instance.instance;
+ }
+
#region IMemoryLocation Members
public void AddressOf (EmitContext ec, AddressOp mode)
this.initializers = initializers;
}
- protected override IMemoryLocation EmitAddressOf (EmitContext ec, AddressOp Mode)
- {
- instance = base.EmitAddressOf (ec, Mode);
-
- if (!initializers.IsEmpty)
- initializers.Emit (ec);
-
- return instance;
- }
-
protected override void CloneTo (CloneContext clonectx, Expression t)
{
base.CloneTo (clonectx, t);
target.initializers = (CollectionOrObjectInitializers) initializers.Clone (clonectx);
}
+ public override bool ContainsEmitWithAwait ()
+ {
+ return base.ContainsEmitWithAwait () || initializers.ContainsEmitWithAwait ();
+ }
+
public override Expression CreateExpressionTree (ResolveContext ec)
{
Arguments args = new Arguments (2);
if (initializers.IsEmpty)
return left_on_stack;
- LocalTemporary temp = target as LocalTemporary;
- if (temp == null) {
+ LocalTemporary temp = null;
+
+ instance = target as LocalTemporary;
+
+ if (instance == null) {
if (!left_on_stack) {
VariableReference vr = target as VariableReference;
-
+
// FIXME: This still does not work correctly for pre-set variables
if (vr != null && vr.IsRef)
target.AddressOf (ec, AddressOp.Load);
left_on_stack = true;
}
- temp = new LocalTemporary (type);
+ if (initializers.ContainsEmitWithAwait ()) {
+ instance = new EmptyExpression (Type).EmitToField (ec) as IMemoryLocation;
+ } else {
+ temp = new LocalTemporary (type);
+ instance = temp;
+ }
}
- instance = temp;
- if (left_on_stack)
+ if (left_on_stack && temp != null)
temp.Store (ec);
initializers.Emit (ec);
if (left_on_stack) {
- temp.Emit (ec);
- temp.Release (ec);
+ if (temp != null) {
+ temp.Emit (ec);
+ temp.Release (ec);
+ } else {
+ ((Expression) instance).Emit (ec);
+ }
}
return left_on_stack;
}
+
+ protected override IMemoryLocation EmitAddressOf (EmitContext ec, AddressOp Mode)
+ {
+ instance = base.EmitAddressOf (ec, Mode);
+
+ if (!initializers.IsEmpty)
+ initializers.Emit (ec);
+
+ return instance;
+ }
}
public class NewAnonymousType : New
{
public int Value;
+ public S (int a1, string a2)
+ {
+ Value = a1;
+ }
+
public void SetValue (int value)
{
Value = value;
class Base
{
- protected int field_int;
+ public int field_int;
protected int field_this;
protected int property_this_counter;
public event Action Event;
+ public Base ()
+ {
+ }
+
+ public Base (int arg, int arg2)
+ {
+ field_int = arg;
+ }
+
public bool PropertyBool {
get {
return true;
return res == 1;
}
+ async Task<bool> NewTest_1 ()
+ {
+ int value = 9;
+ var b = new Base (value, await Task.Factory.StartNew (() => 33));
+ return b.field_int == 9;
+ }
+
+ async Task<bool> NewTest_2 ()
+ {
+ var s = new S (await Task.Factory.StartNew (() => 77), await Task.Factory.StartNew (() => "b"));
+ return s.Value == 77;
+ }
+
+ async Task<int> NewInitTest_1 ()
+ {
+ int value = 9;
+
+ var b = new Base (value, await Task.Factory.StartNew (() => 33)) { };
+ if (b.field_int != 9)
+ return 1;
+
+ b = new Base (value, await Task.Factory.StartNew (() => 11)) {
+ field_int = await Task.Factory.StartNew (() => 12),
+ PropertyInt = await Task.Factory.StartNew (() => 13)
+ };
+
+ if (b.field_int != 25)
+ return 2;
+
+ b = new Base () {
+ field_int = await Task.Factory.StartNew (() => 12),
+ PropertyInt = await Task.Factory.StartNew (() => 13)
+ };
+
+ if (b.field_int != 25)
+ return 3;
+
+ return 0;
+ }
+
+ async Task<int> NewInitTest_2 ()
+ {
+ int value = 9;
+
+ var s = new S (value, await Task.Factory.StartNew (() => "x")) { };
+ if (s.Value != 9)
+ return 1;
+
+ s = new S (value, await Task.Factory.StartNew (() => "y")) {
+ Value = await Task.Factory.StartNew (() => 12)
+ };
+
+ if (s.Value != 12)
+ return 2;
+
+ s = new S () {
+ Value = await Task.Factory.StartNew (() => 13)
+ };
+
+ if (s.Value != 13)
+ return 3;
+
+ return 0;
+ }
+
async Task<bool> NewArrayInitTest_1 ()
{
var a = new int[await Task.Factory.StartNew (() => 5)];
--- /dev/null
+// Compiler options: -langversion:future
+
+using System;
+using System.Threading.Tasks;
+using System.Threading;
+
+interface IFoo
+{
+ int Value { get; set; }
+}
+
+struct S : IFoo
+{
+ public S (int a1, string a2)
+ : this ()
+ {
+ Value = a1;
+ }
+
+ public int Value { get; set; }
+
+ public void SetValue (int value)
+ {
+ Value = value;
+ }
+}
+
+class Tester
+{
+ async Task<T> NewInitTestGen<T> () where T : struct, IFoo
+ {
+ int value = 9;
+
+ var s = new T () {
+ Value = await Task.Factory.StartNew (() => 13)
+ };
+
+ if (s.Value != 13)
+ return new T ();
+
+ return s;
+ }
+
+ public static int Main ()
+ {
+ var t = new Tester().NewInitTestGen<S> ();
+
+ if (!Task.WaitAll (new[] { t }, 1000)) {
+ return 1;
+ }
+
+ if (t.Result.Value != 13)
+ return 2;
+
+ return 0;
+ }
+}
</type>
<type name="Tester+<>c__async1A">
<method name="Void MoveNext()">
- <size>212</size>
+ <size>230</size>
</method>
<method name="Void .ctor()">
<size>36</size>
</type>
<type name="Tester+<>c__async1A">
<method name="Int32 <>m__37()">
- <size>2</size>
+ <size>3</size>
</method>
</type>
<type name="Tester+<>c__async1B">
<size>334</size>
</method>
<method name="Int32 <>m__38()">
- <size>2</size>
- </method>
- <method name="Int32 <>m__39()">
- <size>2</size>
+ <size>3</size>
</method>
<method name="Void .ctor()">
<size>36</size>
</type>
<type name="Tester+<>c__async1C">
<method name="Void MoveNext()">
- <size>232</size>
- </method>
- <method name="Byte <>m__3A()">
- <size>2</size>
+ <size>1009</size>
</method>
<method name="Void .ctor()">
<size>36</size>
</type>
<type name="Tester+<>c__async1D">
<method name="Void MoveNext()">
- <size>420</size>
+ <size>738</size>
</method>
- <method name="UInt16 <>m__3B()">
- <size>2</size>
+ <method name="Void .ctor()">
+ <size>36</size>
</method>
- <method name="UInt16 <>m__3C()">
- <size>2</size>
+ </type>
+ <type name="Tester+<>c__async1E">
+ <method name="Void MoveNext()">
+ <size>212</size>
</method>
<method name="Void .ctor()">
<size>36</size>
</method>
</type>
- <type name="Tester+<>c__async1E">
+ <type name="Tester+<>c__async1F">
<method name="Void MoveNext()">
- <size>250</size>
+ <size>334</size>
</method>
- <method name="S <>m__3D()">
- <size>18</size>
+ <method name="Void .ctor()">
+ <size>36</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async20">
+ <method name="Void MoveNext()">
+ <size>232</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>36</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async21">
+ <method name="Void MoveNext()">
+ <size>420</size>
</method>
<method name="Void .ctor()">
<size>36</size>
</method>
</type>
+ <type name="Tester+<>c__async22">
+ <method name="Void MoveNext()">
+ <size>250</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>36</size>
+ </method>
+ </type>
+ <type name="S">
+ <method name="Void .ctor(Int32, String)">
+ <size>8</size>
+ </method>
+ </type>
+ <type name="Base">
+ <method name="Void .ctor(Int32, Int32)">
+ <size>14</size>
+ </method>
+ </type>
+ <type name="Tester">
+ <method name="System.Threading.Tasks.Task`1[System.Boolean] NewTest_1()">
+ <size>27</size>
+ </method>
+ <method name="System.Threading.Tasks.Task`1[System.Boolean] NewTest_2()">
+ <size>27</size>
+ </method>
+ <method name="System.Threading.Tasks.Task`1[System.Int32] NewInitTest_1()">
+ <size>27</size>
+ </method>
+ <method name="System.Threading.Tasks.Task`1[System.Int32] NewInitTest_2()">
+ <size>27</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async1B">
+ <method name="System.String <>m__39()">
+ <size>6</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async1C">
+ <method name="Int32 <>m__3A()">
+ <size>3</size>
+ </method>
+ <method name="Int32 <>m__3B()">
+ <size>3</size>
+ </method>
+ <method name="Int32 <>m__3C()">
+ <size>3</size>
+ </method>
+ <method name="Int32 <>m__3D()">
+ <size>3</size>
+ </method>
+ <method name="Int32 <>m__3E()">
+ <size>3</size>
+ </method>
+ <method name="Int32 <>m__3F()">
+ <size>3</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async1D">
+ <method name="System.String <>m__40()">
+ <size>6</size>
+ </method>
+ <method name="System.String <>m__41()">
+ <size>6</size>
+ </method>
+ <method name="Int32 <>m__42()">
+ <size>3</size>
+ </method>
+ <method name="Int32 <>m__43()">
+ <size>3</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async1E">
+ <method name="Int32 <>m__44()">
+ <size>2</size>
+ </method>
+ </type>
<type name="Tester+<>c__async1F">
+ <method name="Int32 <>m__45()">
+ <size>2</size>
+ </method>
+ <method name="Int32 <>m__46()">
+ <size>2</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async20">
+ <method name="Byte <>m__47()">
+ <size>2</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async21">
+ <method name="UInt16 <>m__48()">
+ <size>2</size>
+ </method>
+ <method name="UInt16 <>m__49()">
+ <size>2</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async22">
+ <method name="S <>m__4A()">
+ <size>18</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async23">
<method name="Void MoveNext()">
<size>201</size>
</method>
- <method name="Int32 <>m__3E()">
+ <method name="Int32 <>m__4B()">
<size>2</size>
</method>
<method name="Void .ctor()">
<size>36</size>
</method>
</type>
- <type name="Tester+<>c__async20">
+ <type name="Tester+<>c__async24">
<method name="Void MoveNext()">
<size>272</size>
</method>
- <method name="Int32 <>m__3F()">
+ <method name="Int32 <>m__4C()">
<size>2</size>
</method>
<method name="Void .ctor()">
<size>36</size>
</method>
</type>
- <type name="Tester+<>c__async21">
+ <type name="Tester+<>c__async25">
<method name="Void MoveNext()">
<size>636</size>
</method>
- <method name="Int32 <>m__40()">
+ <method name="Int32 <>m__4D()">
<size>3</size>
</method>
- <method name="Int32 <>m__41()">
+ <method name="Int32 <>m__4E()">
<size>2</size>
</method>
- <method name="Int32 <>m__42()">
+ <method name="Int32 <>m__4F()">
<size>2</size>
</method>
<method name="Void .ctor()">
<size>36</size>
</method>
</type>
- <type name="Tester+<>c__async22">
+ <type name="Tester+<>c__async26">
<method name="Void MoveNext()">
<size>441</size>
</method>
- <method name="System.String <>m__43()">
+ <method name="System.String <>m__50()">
<size>6</size>
</method>
- <method name="System.String <>m__44()">
+ <method name="System.String <>m__51()">
<size>6</size>
</method>
- <method name="System.String <>m__45()">
+ <method name="System.String <>m__52()">
<size>2</size>
</method>
<method name="Void .ctor()">
</method>
</type>
</test>
+ <test name="test-async-15.cs">
+ <type name="S">
+ <method name="Int32 get_Value()">
+ <size>7</size>
+ </method>
+ <method name="Void set_Value(Int32)">
+ <size>8</size>
+ </method>
+ <method name="Void SetValue(Int32)">
+ <size>8</size>
+ </method>
+ <method name="Void .ctor(Int32, String)">
+ <size>8</size>
+ </method>
+ </type>
+ <type name="Tester">
+ <method name="System.Threading.Tasks.Task`1[T] NewInitTestGen[T]()">
+ <size>27</size>
+ </method>
+ <method name="Int32 Main()">
+ <size>63</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="Tester+<>c__async0`1[T]">
+ <method name="Void MoveNext()">
+ <size>272</size>
+ </method>
+ <method name="Int32 <>m__0()">
+ <size>3</size>
+ </method>
+ <method name="Void .ctor()">
+ <size>36</size>
+ </method>
+ </type>
+ </test>
<test name="test-cls-00.cs">
<type name="CLSCLass_6">
<method name="Void .ctor()">