public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder) { var amd = stack.QueryAttribute <AsyncMethodDecompiler>(); if (amd != null && amd.ImplStyle == EAsyncImplStyle.FSM) { return(false); } object[] outArgs; object result; stack.TryGetReturnValueSample((MethodInfo)callee, args, out outArgs, out result); var fspec = new FunctionSpec(typeof(Task)) { CILRep = callee }; var fcall = new FunctionCall() { Callee = fspec, Arguments = args.Select(a => a.Expr).ToArray(), ResultType = TypeDescriptor.GetTypeOf(result) }; stack.Push(fcall, result); return(true); }
public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder) { var stateLookup = stack.QueryAttribute <IStateLookup>(); if (stateLookup == null) { var pd = decompilee as ProcessDescriptor; if (pd == null) { var md = decompilee as MethodDescriptor; if (md == null) { throw new InvalidOperationException("Unsupported code descriptor: " + decompilee); } pd = md.CallingProcess; } var pred = pd.Instance.Predicate; var predElem = stack.GetCallExpression( pred.Method, new StackElement(LiteralReference.CreateConstant(pred.Target), pred.Target, EVariability.Constant)); var fspec = new FunctionSpec(typeof(void)) { CILRep = callee, IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitUntil) }; builder.Call(fspec, new Expression[] { predElem.Expr }); } else { builder.Store( stateLookup.NextStateSignal, stateLookup.GetStateExpression(stack.CurrentILIndex)); builder.Return(); } return(true); }
public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder) { var stateLookup = stack.QueryAttribute <IStateLookup>(); if (stateLookup == null) { //throw new InvalidOperationException("Process calling Issue(): Please use [TransformIntoFSM] attribute for proper translation."); return(false); } else { IEnumerable <TAVerb> coStates = (IEnumerable <TAVerb>)args[1].Sample; stateLookup.ImplementCoState(stack.CurrentILIndex, coStates, 0, builder); } return(true); }
public override void RewriteWrite(CodeDescriptor decompilee, FieldInfo field, object instance, StackElement value, IDecompiler stack, IFunctionBuilder builder) { var me = stack.QueryAttribute<AsyncMethodDecompiler>(); me._tasks[field.Name] = value; }
public override void RewriteRead(CodeDescriptor decompilee, FieldInfo field, object instance, IDecompiler stack, IFunctionBuilder builder) { var me = stack.QueryAttribute<AsyncMethodDecompiler>(); var elem = (StackElement)me._tasks[field.Name]; stack.Push(elem); }
public override void RewriteWrite(CodeDescriptor decompilee, FieldInfo field, object instance, StackElement value, IDecompiler stack, IFunctionBuilder builder) { var me = stack.QueryAttribute<AsyncMethodDecompiler>(); var v = me._argFields[field.Name]; if (!me._declared.Contains(v)) { builder.DeclareLocal(v); me._declared.Add(v); } builder.Store(v, value.Expr); if (value.Sample != null) v.UpgradeType(TypeDescriptor.GetTypeOf(value.Sample)); if (me._curSI != null) me._curSI.LVState[field.Name] = value.Sample; }
public override void RewriteRead(CodeDescriptor decompilee, FieldInfo field, object instance, IDecompiler stack, IFunctionBuilder builder) { var me = stack.QueryAttribute<AsyncMethodDecompiler>(); var v = me._argFields[field.Name]; if (!me._declared.Contains(v)) { builder.DeclareLocal(v); me._declared.Add(v); } var lr = (LiteralReference)v; stack.Push(lr, v.Type.GetSampleInstance(ETypeCreationOptions.ForceCreation)); }
public override void RewriteWrite(CodeDescriptor decompilee, FieldInfo field, object instance, StackElement value, IDecompiler stack, IFunctionBuilder builder) { var me = stack.QueryAttribute<AsyncMethodDecompiler>(); try { field.SetValue(me._fsmInstance, value.Sample); } catch (Exception) { var task = me.GetTaskFromAwaiter(value.Sample); var awaiterType = field.FieldType; var targetAwaiter = Activator.CreateInstance(awaiterType); var targetAwaiterField = awaiterType.GetField("m_task", BindingFlags.Instance | BindingFlags.NonPublic); targetAwaiterField.SetValue(targetAwaiter, task); field.SetValue(me._fsmInstance, targetAwaiter); } }
public override void RewriteRead(CodeDescriptor decompilee, FieldInfo field, object instance, IDecompiler stack, IFunctionBuilder builder) { var me = stack.QueryAttribute<AsyncMethodDecompiler>(); var awaiter = field.GetValue(me._fsmInstance); var lr = LiteralReference.CreateConstant(awaiter); stack.Push(new StackElement(lr, awaiter, Msil.EVariability.Constant)); }
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; }
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.FSM) throw new InvalidOperationException("Awaiting other tasks is only possible when decompiling to FSM."); ctx.ImplementAwait(decompilee, callee, args, stack, builder); 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; }
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."); var style = ctx.ImplStyle; if (style == EAsyncImplStyle.Sequential) { ctx.ImplementAwait(decompilee, callee, args, stack, builder); } bool flag = style == EAsyncImplStyle.Sequential; var lr = LiteralReference.CreateConstant(flag); stack.Push(new StackElement(lr, flag, Msil.EVariability.Constant)); return true; }
public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder) { var amd = stack.QueryAttribute<AsyncMethodDecompiler>(); if (amd != null && amd.ImplStyle == EAsyncImplStyle.FSM) { return false; } object[] outArgs; object result; stack.TryGetReturnValueSample((MethodInfo)callee, args, out outArgs, out result); var fspec = new FunctionSpec(typeof(Task)) { CILRep = callee }; var fcall = new FunctionCall() { Callee = fspec, Arguments = args.Select(a => a.Expr).ToArray(), ResultType = TypeDescriptor.GetTypeOf(result) }; stack.Push(fcall, result); return true; }