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"); }