Ejemplo n.º 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);
        }
Ejemplo n.º 2
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);
            }
Ejemplo n.º 3
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);
            }
Ejemplo n.º 4
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);
            }
Ejemplo n.º 5
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);
            }
Ejemplo n.º 6
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);
        }