Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
            public override bool Rewrite(
                CodeDescriptor decompilee,
                Expression waitObject,
                Analysis.IDecompiler stack,
                IFunctionBuilder builder)
            {
                var fspec = new FunctionSpec(typeof(void))
                {
                    IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitFor)
                };

                builder.Call(fspec, waitObject);
                return(true);
            }
Example #4
0
 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);
 }
Example #5
0
            public override bool Rewrite(CodeDescriptor decompilee, System.Reflection.MethodBase callee, Analysis.StackElement[] args, Analysis.IDecompiler stack, IFunctionBuilder builder)
            {
                Array arr = (Array)args[0].Sample;

                if (arr == null)
                {
                    throw new InvalidOperationException("Unable to deduce array length");
                }

                int  numElems = arr.Length;
                Type tTE      = arr.GetType().GetElementType();
                Type tTA;

                callee.IsFunction(out tTA);
                FunctionCall      newCall = IntrinsicFunctions.NewArray(tTE, LiteralReference.CreateConstant(numElems), arr);
                FunctionSpec      fspec   = (FunctionSpec)newCall.Callee;
                IntrinsicFunction ifun    = fspec.IntrinsicRep;
                ArrayParams       aparams = (ArrayParams)ifun.Parameter;

                for (int i = 0; i < numElems; i++)
                {
                    aparams.Elements[i] = IntrinsicFunctions.GetArrayElement(
                        args[0].Expr,
                        LiteralReference.CreateConstant(i));
                }

                object sample = null;

                try
                {
                    sample = callee.Invoke(arr);
                }
                catch (Exception)
                {
                }

                Expression conv = IntrinsicFunctions.Cast(newCall, arr.GetType(), tTA);

                stack.Push(conv, sample);
                return(true);
            }
Example #6
0
            public override bool Rewrite(Meta.CodeDescriptor decompilee, SysDOM.Expression waitObject, Analysis.IDecompiler stack, SysDOM.IFunctionBuilder builder)
            {
                var evt    = waitObject.ResultType.GetSampleInstance();
                var sevent = evt as Event;

                if (sevent == null)
                {
                    // This workaround is for the following situation:
                    //   Signal s;
                    //   await s;
                    // This will actually await the "changed event" which is associated with the signal. However, decompilation
                    // will treat the signal instance as the awaited object and pass a Signal instance instead of the event.
                    // The code will try to restore the Event instance from the Awaiter.
                    Awaiter awaiter = null;
                    try
                    {
                        awaiter = ((object)AwaitableExtensionMethods.GetAwaiter((dynamic)evt)) as Awaiter;
                    }
                    catch
                    {
                    }
                    if (awaiter == null)
                    {
                        throw new InvalidOperationException("Unable to resolve awaited MultiEvent");
                    }
                    sevent = awaiter._event;
                }

                var signal    = (SignalBase)sevent.Owner;
                var signalRef = SignalRef.Create(signal, SignalRef.EReferencedProperty.Instance);
                var arg       = (LiteralReference)signalRef;

                var fspec = new FunctionSpec(typeof(void))
                {
                    IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitOn)
                };

                builder.Call(fspec, arg);
                return(true);
            }
Example #7
0
            public override bool Rewrite(Meta.CodeDescriptor decompilee, SysDOM.Expression waitObject, Analysis.IDecompiler stack, SysDOM.IFunctionBuilder builder)
            {
                var evt    = waitObject.ResultType.GetSampleInstance();
                var mevent = evt as MultiEvent;

                if (mevent == null)
                {
                    throw new InvalidOperationException("Unable to resolve awaited MultiEvent");
                }

                var events     = mevent._events.Cast <Event>();
                var signals    = events.Select(e => (SignalBase)e.Owner);
                var signalRefs = signals.Select(s => SignalRef.Create(s, SignalRef.EReferencedProperty.Instance));
                var args       = signalRefs.Select(sr => (LiteralReference)sr).ToArray();

                var fspec = new FunctionSpec(typeof(void))
                {
                    IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitOn)
                };

                builder.Call(fspec, args);
                return(true);
            }
Example #8
0
            public override bool Rewrite(Meta.CodeDescriptor decompilee, SysDOM.Expression waitObject, Analysis.IDecompiler stack, SysDOM.IFunctionBuilder builder)
            {
                var evt     = waitObject.ResultType.GetSampleInstance();
                var peevent = evt as PredicatedEvent;

                if (peevent == null)
                {
                    throw new InvalidOperationException("Unable to resolve awaited PredicatedEvent");
                }

                var pred = peevent._pred;
                var rwc  = pred.Method.GetCustomOrInjectedAttribute <RewriteCall>();

                if (rwc == null)
                {
                    throw new InvalidOperationException("Awaited predicate is not synthesizable.");
                }

                var lr   = LiteralReference.CreateConstant(pred.Target);
                var se   = new StackElement(lr, pred.Target, Analysis.Msil.EVariability.Constant);
                var pstk = stack.CreatePrivateStack();

                if (!rwc.Rewrite(decompilee, pred.Method, new StackElement[] { se }, pstk, builder))
                {
                    throw new InvalidOperationException("Unable to implement awaited predicate.");
                }

                var predEx = pstk.Pop();
                var fspec  = new FunctionSpec(typeof(void))
                {
                    IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitUntil)
                };

                builder.Call(fspec, predEx.Expr);

                return(true);
            }
Example #9
0
        public void AcceptCall(CallStatement stmt)
        {
            CreateLabelForNextInstruction(stmt);

            FunctionSpec fspec = stmt.Callee as FunctionSpec;

            if (fspec == null)
            {
                throw new NotSupportedException();
            }

            if (fspec.CILRep != null)
            {
                var cmc = fspec.CILRep.GetCustomOrInjectedAttribute <CompileMethodCall>();
                if (cmc != null)
                {
                    cmc.Compile(stmt, _backend);
                    return;
                }
            }

            IntrinsicFunction ifun = fspec.IntrinsicRep;

            if (ifun != null)
            {
                switch (ifun.Action)
                {
                case IntrinsicFunction.EAction.Wait:
                    return;     // ignore for now

                default:
                    throw new NotSupportedException();
                }
            }

            throw new NotSupportedException();
        }
Example #10
0
        public override bool Rewrite(CodeDescriptor decompilee, Expression waitObject, IDecompiler stack, IFunctionBuilder builder)
        {
            if (stack.HasAttribute <Analysis.M2M.HLS>())
            {
                return(true);
            }

            var       curps = DesignContext.Instance.CurrentProcess;
            SLSignal  clk   = (SLSignal)curps.Sensitivity[0].Owner;
            SignalRef srEdge;

            if (curps.Predicate.Equals((Func <bool>)clk.RisingEdge))
            {
                srEdge = SignalRef.Create(clk.Descriptor, SignalRef.EReferencedProperty.RisingEdge);
            }
            else
            {
                srEdge = SignalRef.Create(clk.Descriptor, SignalRef.EReferencedProperty.FallingEdge);
            }
            var lrEdge = new LiteralReference(srEdge);

            int  nwait      = 0;
            var  nwaitEx    = waitObject.Children[0];
            bool nwaitConst = nwaitEx.IsConst();

            if (nwaitConst)
            {
                nwait = (int)TypeConversions.ConvertValue(
                    nwaitEx.Eval(DefaultEvaluator.DefaultConstEvaluator),
                    typeof(int));
            }

            var fspec = new FunctionSpec(typeof(void))
            {
                IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitUntil)
            };

            Variable         v   = null;
            LiteralReference lrV = null;

            if (!nwaitConst || nwait > 3)
            {
                v = new Variable(typeof(int))
                {
                    Name = "_wait_i" + (ictr++)
                };
                builder.DeclareLocal(v);
                lrV = new LiteralReference(v);
                builder.Store(v, LiteralReference.CreateConstant((int)0));
                var loop = builder.Loop();
                builder.If(Expression.Equal(lrV, nwaitEx));
                {
                    builder.Break(loop);
                }
                builder.EndIf();
            }
            int ncalls = 1;

            if (nwaitConst && nwait <= 3)
            {
                ncalls = nwait;
            }
            for (int i = 0; i < ncalls; i++)
            {
                builder.Call(fspec, lrEdge);
            }
            if (!nwaitConst || nwait > 3)
            {
                builder.Store(v, lrV + LiteralReference.CreateConstant((int)1));
                builder.EndLoop();
            }
            return(true);
        }
            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.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;
            }
        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)
        {
            Type returnType;
            if (callee.ReturnsSomething(out returnType))
            {
                dynamic awaiter = args[0].Sample;
                if ((object)awaiter != null)
                {
                    if (!awaiter.IsCompleted)
                        throw new InvalidOperationException("Task not completed - what are you awaiting for?");

                    object resultSample = awaiter.GetResult();
                    var resultType = resultSample.GetType();
                    var fspec = new FunctionSpec(resultType)
                    {
                        IntrinsicRep = IntrinsicFunctions.GetAsyncResult(awaiter)
                    };
                    var fcall = new FunctionCall()
                    {
                        Callee = fspec,
                        Arguments = new Expression[0],
                        ResultType = resultType
                    };
                    stack.Push(fcall, resultSample);
                }
            }
            return true;
        }
Example #15
0
        public int TransformFunction(FunctionCall expr)
        {
            FunctionSpec fspec = expr.Callee as FunctionSpec;

            if (fspec == null)
            {
                throw new NotSupportedException();
            }

            IntrinsicFunction ifun = fspec.IntrinsicRep;

            if (ifun == null)
            {
                throw new NotSupportedException();
            }

            switch (ifun.Action)
            {
            case IntrinsicFunction.EAction.Convert:
            {
                // only first child should be evaluated, following children are conversion arguments.
                // These will be implicitly defined by the result type of the instruction
                expr.Children[0].Accept(this);
                ExtractCILIndex(expr);
                var cparams = (CastParams)ifun.Parameter;
                Emit(ISet.Convert(cparams.Reinterpret), expr, 1, expr.ResultType);
            }
                return(0);

            case IntrinsicFunction.EAction.Sign:
                expr.Children[0].Accept(this);
                ExtractCILIndex(expr);
                Emit(ISet.Sign(), expr, 1, expr.ResultType);
                return(0);

            case IntrinsicFunction.EAction.Resize:
                expr.Children[0].Accept(this);
                Emit(ISet.Convert(), expr, 1, expr.ResultType);
                ExtractCILIndex(expr);
                return(0);

            case IntrinsicFunction.EAction.Slice:
                if (expr.Children.Length == 3)
                {
                    expr.Children[0].Accept(this);
                    expr.Children[1].Accept(this);
                    expr.Children[2].Accept(this);
                    Emit(ISet.Slice(), expr, 3, expr.ResultType);
                }
                else
                {
                    expr.Children[0].Accept(this);
                    var range = (Range)ifun.Parameter;
                    Emit(ISet.SliceFixI(range), expr, 1, expr.ResultType);
                }
                return(0);

            case IntrinsicFunction.EAction.Abs:
                expr.Children[0].Accept(this);
                Emit(ISet.Abs(), expr, 1, expr.ResultType);
                return(0);

            case IntrinsicFunction.EAction.Sqrt:
                expr.Children[0].Accept(this);
                Emit(ISet.Sqrt(), expr, 1, expr.ResultType);
                return(0);

            case IntrinsicFunction.EAction.GetArrayElement:
            {
                var aex  = expr.Children[0];
                var alr  = (LiteralReference)aex;
                var alit = alr.ReferencedObject;
                var arr  = (Array)aex.ResultType.GetSampleInstance();
                var far  = new FixedArrayRef(alit, arr);
                expr.Children[1].Accept(this);
                Emit(ISet.LdelemFixA(far), expr, 1, expr.ResultType);
            }
                return(0);

            case IntrinsicFunction.EAction.XILOpCode:
            {
                foreach (var child in expr.Children)
                {
                    child.Accept(this);
                }
                var opcode = (XILInstr)ifun.Parameter;
                Emit(opcode, expr, expr.Children.Length, expr.ResultType.Unpick());
            }
                return(0);

            case IntrinsicFunction.EAction.TupleSelect:
            {
                int item = (int)ifun.Parameter;
                var lr   = expr.Children[0] as LiteralReference;
                if (lr == null)
                {
                    throw new NotSupportedException("TupleSelect must refer to a literal");
                }
                var tuple = lr.ReferencedObject as Variable;
                if (tuple == null)
                {
                    throw new NotSupportedException("TupleSelect must refer to a local variable");
                }
                var itemVars = Unpick(tuple);
                var itemLr   = new LiteralReference(itemVars[item]);
                TransformLiteralReference(itemLr);
            }
                return(0);

            default:
                throw new NotImplementedException();
            }
        }
Example #16
0
        private bool TryInline(ICallable callable, Expression[] args, out IStorableLiteral retv)
        {
            FunctionSpec fspec = callable as FunctionSpec;

            retv = null;
            if (fspec != null)
            {
                // Do not inline intrinsic functions
                if (fspec.IntrinsicRep != null)
                {
                    return(false);
                }

                var md = fspec.SpecialSysDOMRep;
                if (md != null)
                {
                    var fun = md.Implementation;

                    InlineVerifier.CheckAllLocalsDeclared(fun);

                    // Recursion?
                    if (_funStack.Contains(fun))
                    {
                        return(false);
                    }

                    if (fun.OutputVariables.Count == 0)
                    {
                        if (!fspec.ResultType.CILType.Equals(typeof(void)))
                        {
                            string           name = _sim.GetUniqueName("$ret", new object());
                            IStorableLiteral rv   = new Variable(fspec.ResultType)
                            {
                                Name = name
                            };
                            retv = _locals[Tuple.Create(fun, rv)];
                        }
                    }
                    else if (fun.OutputVariables.Count == 1)
                    {
                        retv = _locals[Tuple.Create(fun, fun.OutputVariables[0])];
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    // account for possible "this" argument
                    int j = args.Length - fun.InputVariables.Count;

                    for (int i = j; i < args.Length; i++)
                    {
                        Expression rhs = args[i].Transform(this);
                        var        lhs = _locals[Tuple.Create(fun, fun.InputVariables[i - j])];
                        Store(lhs, rhs);
                    }
                    if (retv != null)
                    {
                        _retStack.Push(retv);
                    }
                    _funStack.Push(fun);
                    _getOutStack.Push(new List <GotoStatement>());
                    fun.Body.Accept(this);
                    _funStack.Pop();
                    if (retv != null)
                    {
                        _retStack.Pop();
                    }
                    Nop();
                    foreach (var getOut in _getOutStack.Pop())
                    {
                        getOut.Target = LastStatement;
                    }

                    _inlinedFunctions.Add(fun);

                    return(true);
                }
                else
                {
                    //System.Diagnostics.Debug.Assert(false, "function not decompiled - bug?");
                }
            }
            return(false);
        }
Example #17
0
        public override bool Rewrite(CodeDescriptor decompilee, Expression waitObject, IDecompiler stack, IFunctionBuilder builder)
        {
            if (stack.HasAttribute<Analysis.M2M.HLS>())
            {
                return true;
            }

            var curps = DesignContext.Instance.CurrentProcess;
            SLSignal clk = (SLSignal)curps.Sensitivity[0].Owner;
            SignalRef srEdge;
            if (curps.Predicate.Equals((Func<bool>)clk.RisingEdge))
                srEdge = SignalRef.Create(clk.Descriptor, SignalRef.EReferencedProperty.RisingEdge);
            else
                srEdge = SignalRef.Create(clk.Descriptor, SignalRef.EReferencedProperty.FallingEdge);
            var lrEdge = new LiteralReference(srEdge);

            int nwait = 0;
            var nwaitEx = waitObject.Children[0];
            bool nwaitConst = nwaitEx.IsConst();
            if (nwaitConst)
            {
                nwait = (int)TypeConversions.ConvertValue(
                        nwaitEx.Eval(DefaultEvaluator.DefaultConstEvaluator),
                        typeof(int));
            }

            var fspec = new FunctionSpec(typeof(void))
            {
                IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitUntil)
            };

            Variable v = null;
            LiteralReference lrV = null;

            if (!nwaitConst || nwait > 3)
            {
                v = new Variable(typeof(int))
                {
                    Name = "_wait_i" + (ictr++)
                };
                builder.DeclareLocal(v);
                lrV = new LiteralReference(v);
                builder.Store(v, LiteralReference.CreateConstant((int)0));
                var loop = builder.Loop();
                builder.If(Expression.Equal(lrV, nwaitEx));
                {
                    builder.Break(loop);
                }
                builder.EndIf();
            }
            int ncalls = 1;
            if (nwaitConst && nwait <= 3)
                ncalls = nwait;
            for (int i = 0; i < ncalls; i++)
            {
                builder.Call(fspec, lrEdge);
            }
            if (!nwaitConst || nwait > 3)
            {
                builder.Store(v, lrV + LiteralReference.CreateConstant((int)1));
                builder.EndLoop();
            }
            return true;
        }
Example #18
0
        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)
        {
            IntrinsicFunction ifun = new IntrinsicFunction(Kind, Parameter)
            {
                MethodModel = callee
            };

            int skip = SkipFirstArg ? 1 : 0;
            Expression[] eargs = args.Skip(skip).Select(arg => arg.Expr).ToArray();
            Type returnType;
            if (!callee.IsFunctionOrCtor(out returnType))
            {
                FunctionSpec fspec = new FunctionSpec(typeof(void))
                {
                    CILRep = callee,
                    IntrinsicRep = ifun
                };
                builder.Call(fspec, eargs);
            }
            else
            {
                object[] outArgs;
                object rsample = null;
                if (callee is MethodInfo &&
                    !callee.HasCustomOrInjectedAttribute<IDoNotCallOnDecompilation>())
                {
                    stack.TryGetReturnValueSample((MethodInfo)callee, args, out outArgs, out rsample);
                }
                TypeDescriptor rtype;
                if (rsample != null)
                    rtype = TypeDescriptor.GetTypeOf(rsample);
                else
                    rtype = returnType;
                FunctionSpec fspec = new FunctionSpec(rtype)
                {
                    CILRep = callee,
                    IntrinsicRep = ifun
                };
                FunctionCall fcall = new FunctionCall()
                {
                    Callee = fspec,
                    Arguments = eargs,
                    ResultType = rtype,
                    SetResultTypeClass = EResultTypeClass.ObjectReference
                };
                stack.Push(fcall, rsample);
            }
            return true;
        }
        public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder)
        {
            object[] outArgs;
            object rsample = null;
            if (callee is MethodInfo &&
                !callee.HasCustomOrInjectedAttribute<IDoNotCallOnDecompilation>())
            {
                stack.TryGetReturnValueSample((MethodInfo)callee, args, out outArgs, out rsample);
            }
            Type returnType;
            callee.IsFunctionOrCtor(out returnType);
            TypeDescriptor rtype;
            if (rsample != null)
                rtype = TypeDescriptor.GetTypeOf(rsample);
            else
                rtype = returnType;

            IntrinsicFunction ifun;
            FunctionCall fcall;
            if (args[1].Variability == EVariability.Constant &&
                args[2].Variability == EVariability.Constant)
            {
                // constant arguments case
                int first = (int)TypeConversions.ConvertValue(args[1].Sample, typeof(int));
                int second = (int)TypeConversions.ConvertValue(args[2].Sample, typeof(int));
                var range = new Range(first, second, EDimDirection.Downto);
                ifun = new IntrinsicFunction(IntrinsicFunction.EAction.Slice, range)
                {
                    MethodModel = callee
                };
                var fspec = new FunctionSpec(rtype)
                {
                    CILRep = callee,
                    IntrinsicRep = ifun
                };
                fcall = new FunctionCall()
                {
                    Callee = fspec,
                    Arguments = new Expression[] { args[0].Expr },
                    ResultType = rtype,
                    SetResultTypeClass = EResultTypeClass.ObjectReference
                };
            }
            else
            {
                ifun = new IntrinsicFunction(IntrinsicFunction.EAction.Slice)
                {
                    MethodModel = callee
                };
                var fspec = new FunctionSpec(rtype)
                {
                    CILRep = callee,
                    IntrinsicRep = ifun
                };
                fcall = new FunctionCall()
                {
                    Callee = fspec,
                    Arguments = args.Select(arg => arg.Expr).ToArray(),
                    ResultType = rtype,
                    SetResultTypeClass = EResultTypeClass.ObjectReference
                };
            }
            stack.Push(fcall, rsample);
            return true;
        }