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