public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args,
                              IDecompiler decomp, IFunctionBuilder builder)
 {
     Expression[] elements = null;
     if (args.Length == 1)
     {
         Expression valarr = args[0].Expr;
         valarr = decomp.ResolveVariableReference(decomp.CurrentILIndex, valarr);
         FunctionCall newarrCall = valarr as FunctionCall;
         if (newarrCall != null)
         {
             FunctionSpec      fspec = newarrCall.Callee as FunctionSpec;
             IntrinsicFunction ifun  = fspec == null ? null : fspec.IntrinsicRep;
             if (ifun != null && ifun.Action == IntrinsicFunction.EAction.NewArray)
             {
                 ArrayParams aparams = (ArrayParams)ifun.Parameter;
                 if (aparams.IsStatic)
                 {
                     newarrCall.IsInlined = true;
                     for (int i = 0; i < aparams.Elements.Length; i++)
                     {
                         aparams.Elements[i].IsInlined = true;
                     }
                     elements = aparams.Elements;
                 }
             }
         }
     }
     else
     {
         elements = args.Select(arg => arg.Expr).ToArray();
     }
     if (elements == null)
     {
         throw new NotImplementedException();
     }
     MakeStringArray(elements);
     decomp.Push(
         IntrinsicFunctions.StringConcat(elements),
         "");
     return(true);
 }
            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 void ImplementAwait(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder)
 {
     var awaiterCallExpr = stack.ResolveVariableReference(stack.CurrentILIndex, args[0].Expr);
     var awaiterCall = awaiterCallExpr as FunctionCall;
     if (awaiterCall == null)
         throw new InvalidOperationException("Unable to resolve awaited object.");
     var waitObject = awaiterCall.Arguments[0];
     var awaiterType = args[0].Expr.ResultType.CILType;
     var rw = awaiterType.GetCustomOrInjectedAttribute<RewriteAwait>();
     if (rw == null)
     {
         var fcall = waitObject as FunctionCall;
         if (fcall != null)
         {
             var fspec = fcall.Callee as FunctionSpec;
             if (fspec != null && fspec.CILRep != null)
                 rw = fspec.CILRep.GetCustomOrInjectedAttribute<RewriteAwait>();
         }
     }
     if (rw != null)
         rw.Rewrite(decompilee, waitObject, stack, builder);
     else
         throw new InvalidOperationException("Unable to find await implementor");
 }