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