Improved DateTime parsing of years.
[mono.git] / mcs / mcs / async.cs
index 2a339b41b5f67b604033f3709c9d72469ec69f16..6ffa92aa06a3f9cda8df1e97a0cbf67eaa719206 100644 (file)
@@ -74,10 +74,6 @@ namespace Mono.CSharp
 
                protected override Expression DoResolve (ResolveContext rc)
                {
-                       if (rc.HasSet (ResolveContext.Options.FinallyScope)) {
-                               rc.Report.Error (1984, loc,  "The `await' operator cannot be used in the body of a finally clause");
-                       }
-
                        if (rc.HasSet (ResolveContext.Options.LockScope)) {
                                rc.Report.Error (1996, loc,
                                        "The `await' operator cannot be used in the body of a lock statement");
@@ -244,7 +240,7 @@ namespace Mono.CSharp
                        var fe_awaiter = new FieldExpr (awaiter, loc);
                        fe_awaiter.InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, loc);
 
-                               Label skip_continuation = ec.DefineLabel ();
+                       Label skip_continuation = ec.DefineLabel ();
 
                        using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
                                //
@@ -324,10 +320,6 @@ namespace Mono.CSharp
                                return false;
                        }
 
-                       if (bc.HasSet (ResolveContext.Options.CatchScope)) {
-                               bc.Report.Error (1985, loc, "The `await' operator cannot be used in the body of a catch clause");
-                       }
-
                        if (!base.Resolve (bc))
                                return false;
 
@@ -447,6 +439,10 @@ namespace Mono.CSharp
                        get; set;
                }
 
+               public StackFieldExpr HoistedReturnState {
+                       get; set;
+               }
+
                public override bool IsIterator {
                        get {
                                return false;
@@ -464,9 +460,9 @@ namespace Mono.CSharp
                protected override BlockContext CreateBlockContext (BlockContext bc)
                {
                        var ctx = base.CreateBlockContext (bc);
-                       var lambda = bc.CurrentAnonymousMethod as LambdaMethod;
-                       if (lambda != null)
-                               return_inference = lambda.ReturnTypeInference;
+                       var am = bc.CurrentAnonymousMethod as AnonymousMethodBody;
+                       if (am != null)
+                               return_inference = am.ReturnTypeInference;
 
                        ctx.Set (ResolveContext.Options.TryScope);
 
@@ -478,6 +474,24 @@ namespace Mono.CSharp
                        throw new NotImplementedException ();
                }
 
+               public void EmitCatchBlock (EmitContext ec)
+               {
+                       var catch_value = LocalVariable.CreateCompilerGenerated (ec.Module.Compiler.BuiltinTypes.Exception, block, Location);
+
+                       ec.BeginCatchBlock (catch_value.Type);
+                       catch_value.EmitAssign (ec);
+
+                       ec.EmitThis ();
+                       ec.EmitInt ((int) IteratorStorey.State.After);
+                       ec.Emit (OpCodes.Stfld, storey.PC.Spec);
+
+                       ((AsyncTaskStorey) Storey).EmitSetException (ec, new LocalVariableReference (catch_value, Location));
+
+                       ec.Emit (OpCodes.Leave, move_next_ok);
+                       ec.EndExceptionBlock ();
+
+               }
+
                protected override void EmitMoveNextEpilogue (EmitContext ec)
                {
                        var storey = (AsyncTaskStorey) Storey;
@@ -509,7 +523,6 @@ namespace Mono.CSharp
                MethodSpec builder_factory;
                MethodSpec builder_start;
                PropertySpec task;
-               LocalVariable hoisted_return;
                int locals_captured;
                Dictionary<TypeSpec, List<Field>> stack_fields;
                Dictionary<TypeSpec, List<Field>> awaiter_fields;
@@ -523,11 +536,7 @@ namespace Mono.CSharp
 
                #region Properties
 
-               public LocalVariable HoistedReturn {
-                       get {
-                               return hoisted_return;
-                       }
-               }
+               public Expression HoistedReturnValue { get; set; }
 
                public TypeSpec ReturnType {
                        get {
@@ -576,7 +585,7 @@ namespace Mono.CSharp
                        return field;
                }
 
-               public Field AddCapturedLocalVariable (TypeSpec type)
+               public Field AddCapturedLocalVariable (TypeSpec type, bool requiresUninitialized = false)
                {
                        if (mutator != null)
                                type = mutator.Mutate (type);
@@ -584,7 +593,7 @@ namespace Mono.CSharp
                        List<Field> existing_fields = null;
                        if (stack_fields == null) {
                                stack_fields = new Dictionary<TypeSpec, List<Field>> ();
-                       } else if (stack_fields.TryGetValue (type, out existing_fields)) {
+                       } else if (stack_fields.TryGetValue (type, out existing_fields) && !requiresUninitialized) {
                                foreach (var f in existing_fields) {
                                        if (f.IsAvailableForReuse) {
                                                f.IsAvailableForReuse = false;
@@ -717,7 +726,7 @@ namespace Mono.CSharp
                        set_state_machine.Block.AddStatement (new StatementExpression (new Invocation (mg, args)));
 
                        if (has_task_return_type) {
-                               hoisted_return = LocalVariable.CreateCompilerGenerated (bt.TypeArguments[0], StateMachineMethod.Block, Location);
+                               HoistedReturnValue = TemporaryVariableReference.Create (bt.TypeArguments [0], StateMachineMethod.Block, Location);
                        }
 
                        return true;
@@ -810,7 +819,7 @@ namespace Mono.CSharp
                        args.Add (new Argument (awaiter, Argument.AType.Ref));
                        args.Add (new Argument (new CompilerGeneratedThis (CurrentType, Location), Argument.AType.Ref));
                        using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
-                               mg.EmitCall (ec, args);
+                               mg.EmitCall (ec, args, true);
                        }
                }
 
@@ -888,7 +897,7 @@ namespace Mono.CSharp
                        args.Add (new Argument (exceptionVariable));
 
                        using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
-                               mg.EmitCall (ec, args);
+                               mg.EmitCall (ec, args, true);
                        }
                }
 
@@ -904,15 +913,15 @@ namespace Mono.CSharp
                        };
 
                        Arguments args;
-                       if (hoisted_return == null) {
+                       if (HoistedReturnValue == null) {
                                args = new Arguments (0);
                        } else {
                                args = new Arguments (1);
-                               args.Add (new Argument (new LocalVariableReference (hoisted_return, Location)));
+                               args.Add (new Argument (HoistedReturnValue));
                        }
 
                        using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
-                               mg.EmitCall (ec, args);
+                               mg.EmitCall (ec, args, true);
                        }
                }