public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder) { var ctx = stack.QueryAttribute<AsyncMethodDecompiler>(); if (ctx.ImplStyle == EAsyncImplStyle.FSM) { if (args.Length == 2 && ctx._curCoFSM.ResultVar != null) { builder.Store(ctx._curCoFSM.ResultVar, args[1].Expr); if (args[1].Expr.ResultType.IsComplete) ctx._curCoFSM.ResultVar.UpgradeType(args[1].Expr.ResultType); } var si = ctx.ForkInitialSI(); var pi = new ProceedWithStateInfo() { TargetState = si, TargetWaitState = false, LambdaTransition = false }; if (ctx._curCoFSM != null && ctx._curCoFSM.DoneVar != null) { var tr = LiteralReference.CreateConstant(true); builder.Store(ctx._curCoFSM.DoneVar, tr); pi.TargetState = null; } var fspec = new FunctionSpec(typeof(void)) { IntrinsicRep = IntrinsicFunctions.ProceedWithState(pi) }; builder.Call(fspec, LiteralReference.CreateConstant(pi)); } return true; }
private void ImplementJoin(JoinParams jp, IAlgorithmBuilder builder, StateInfo sin) { Contract.Requires<ArgumentNullException>(jp != null); Contract.Requires<ArgumentNullException>(builder != null); Contract.Requires<ArgumentNullException>(sin != null); var jspec = new FunctionSpec(typeof(bool)) { IntrinsicRep = IntrinsicFunctions.Join(jp) }; var jcall = new FunctionCall() { Callee = jspec, Arguments = new Expression[0], ResultType = typeof(bool) }; builder.If(jcall); var pi1 = new ProceedWithStateInfo() { TargetState = sin, TargetWaitState = false, LambdaTransition = true }; var pspec1 = new FunctionSpec(typeof(void)) { IntrinsicRep = IntrinsicFunctions.ProceedWithState(pi1) }; builder.Call(pspec1, LiteralReference.CreateConstant(pi1)); builder.Else(); var sin2 = sin.Fork(sin.ILState); var pi2 = new ProceedWithStateInfo() { TargetState = sin, TargetWaitState = true, LambdaTransition = false }; var pspec2 = new FunctionSpec(typeof(void)) { IntrinsicRep = IntrinsicFunctions.ProceedWithState(pi2) }; builder.Call(pspec2, LiteralReference.CreateConstant(pi2)); builder.EndIf(); if (_curCoFSM != null) _curCoFSM.Dependencies.Add(jp.JoinedTask); }
public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder) { var ctx = stack.QueryAttribute<AsyncMethodDecompiler>(); if (ctx == null) throw new InvalidOperationException("Method must be decompiled using AsyncMethodDecompiler."); if (ctx.ImplStyle == EAsyncImplStyle.Sequential) return true; var awaiterCallExpr = stack.ResolveVariableReference(stack.CurrentILIndex, args[1].Expr); var awaiterCall = awaiterCallExpr as FunctionCall; if (awaiterCall != null) { var waitObject = awaiterCall.Arguments[0]; var asyncCall = waitObject as FunctionCall; if (asyncCall != null) { var cspec = asyncCall.Callee as FunctionSpec; if (cspec != null && cspec.CILRep != null && cspec.CILRep.HasCustomOrInjectedAttribute<TickAttribute>()) { var si = ctx.ForkNextSI(); var pi = new ProceedWithStateInfo() { TargetState = si, TargetWaitState = false, LambdaTransition = false }; var fspec = new FunctionSpec(typeof(void)) { IntrinsicRep = IntrinsicFunctions.ProceedWithState(pi) }; builder.Call(fspec, LiteralReference.CreateConstant(pi)); return true; } } } var awaiter = args[1].Sample; var task = ctx.GetTaskFromAwaiter(awaiter); if (task != null) { if (!task.IsCompleted) throw new InvalidOperationException("Task not completed - what are you awaiting for?"); var sin = ctx.ForkNextSI(); sin.HasWaitState = true; var jp = new JoinParams() { JoinedTask = task, Continuation = sin }; sin.JP = jp; ctx.ImplementJoin(jp, builder, sin); } return true; }
internal static IntrinsicFunction ProceedWithState(ProceedWithStateInfo pi) { return new IntrinsicFunction( IntrinsicFunction.EAction.ProceedWithState, pi); }