Ejemplo n.º 1
0
        /// <summary>
        /// Recursively inlines all function calls, i.e. replaces each function call with the content of the called function.
        /// </summary>
        /// <param name="fun">function whose calls shall be inlined</param>
        /// <param name="inlinedFunctions">out parameter to receive an enumeration of all functions which were inlined</param>
        /// <returns>the modified function</returns>
        public static Function InlineCalls(this Function fun, out IEnumerable <Function> inlinedFunctions)
        {
            InlineVerifier.CheckAllLocalsDeclared(fun);
            FunctionInliner fi     = new FunctionInliner(fun);
            Function        result = fi.GetAlgorithm();

            result.Name      = fun.Name;
            inlinedFunctions = fi.InlinedFunctions;
            InlineVerifier.CheckAllLocalsDeclared(result);
            return(result);
        }
Ejemplo n.º 2
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);
        }