Ejemplo n.º 1
0
        private void DecompileStates()
        {
            ProcessDescriptor pd = (ProcessDescriptor)_code;

            _templ = new MSILDecompilerTemplate()
            {
                Instance                 = pd.Instance.Owner,
                ArgumentValues           = new object[0],
                Decompilee               = _code,
                Method                   = _code.Method,
                Code                     = MethodCode.Create(_code.Method),
                DisallowReturnStatements = true,
                NestLoopsDeeply          = true,
                TryToEliminateLoops      = true,
                DisallowConditionals     = true
            };
            LocalVariableState initialState = _templ.ExportLocalVariableState();

            GetStateInfo(_dissectionPoints[0], initialState);

            while (_stateWorkQueue.Any())
            {
                StateInfo      si     = _stateWorkQueue.Dequeue();
                MSILDecompiler decomp = new MSILDecompiler(_code, si.CFG, _instance)
                {
                    Template = _templ
                };
                _templ.AddAttribute(this);
                _templ.ImportLocalVariableState(si.LVState);
                IDecompilationResult result = decomp.Decompile();
                si.StateFun = result.Decompiled;
                _calledMethods.AddRange(result.CalledMethods);
                _referencedFields.AddRange(result.ReferencedFields);
            }
        }
Ejemplo n.º 2
0
        private void InitCoState(TAVerb tav, CoStateInfo csi)
        {
            MethodCode       csc    = MethodCode.Create(tav.Op.Method);
            MethodDescriptor md     = new MethodDescriptor(tav.Op.Method, new object[0], new EVariability[0]);
            MSILDecompiler   decomp = new MSILDecompiler(md, csc, tav.Op.Target);

            decomp.Template.DisallowReturnStatements = true;
            decomp.Template.NestLoopsDeeply          = true;
            decomp.Template.TryToEliminateLoops      = true;
            decomp.Template.DisallowConditionals     = true;
            IDecompilationResult result = decomp.Decompile();

            csi.StateAction  = result.Decompiled;
            csi.DuringAction = tav.During;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Decompiles the method to an explicit state machine representation
        /// </summary>
        /// <returns>decopmiled method</returns>
        public IDecompilationResult DecompileToFSM()
        {
            InitializeCFGs();

            int numILStates = _stateCFGs.Length;
            var design = _code.GetDesign();
            var owner = _code.Owner as ComponentDescriptor;
            var myps = _code as ProcessDescriptor;

            // Decompile state handlers
            _stateInfos = new Dictionary<StateInfo, StateInfo>();
            var decomp = new MSILDecompiler(_code, _stateCFGs[1], _fsmInstance);
            _curTempl = decomp.Template;
            _curTempl.AddAttribute(this);
            _curTempl.DisallowReturnStatements = true;
            _curTempl.DisallowConditionals = true;
            _curTempl.DisallowLoops = true;
            var lvState = _curTempl.ExportLocalVariableState();
            var startSI = new StateInfo(0);
            foreach (var kvp in _locFields)
                startSI.LVState[kvp.Key] = kvp.Value.Type.GetSampleInstance(ETypeCreationOptions.ForceCreation);
            _stateInfos[startSI] = startSI;
            _curSI = startSI;
            var stateList = new List<StateInfo>();
            stateList.Add(startSI);
            _stateQ = new Queue<StateInfo>();
            startSI.Result = decomp.Decompile();
            while (_stateQ.Any())
            {
                var nextSI = _stateQ.Dequeue();
                _curSI = nextSI.Fork(nextSI.ILState);
                decomp = new MSILDecompiler(_code, _stateCFGs[nextSI.ILState + 1], _fsmInstance);
                _curTempl = decomp.Template;
                _curTempl.AddAttribute(this);
                _curTempl.DisallowReturnStatements = true;
                _curTempl.DisallowConditionals = true;
                _curTempl.DisallowLoops = true;
                _curSI.Result = decomp.Decompile();
                stateList.Add(_curSI);
                _stateInfos[_curSI] = _curSI;
            }

            // Create enumeration type for state
            string prefix = _code.Name;
            string enumName = "t_" + prefix + "_state";
            var stateNames = new List<string>();
            for (int i = 0; i < stateList.Count; i++)
            {
                string name;
                if (stateList[i].HasWaitState)
                {
                    name = enumName + "_await_" + i;
                    stateNames.Add(name);
                }
                name = enumName + "_" + i;
                stateNames.Add(name);
            }
            int numStates = stateNames.Count;
            Statement[] states;
            SignalDescriptor stateSignal = null;

            if (numStates > 1)
            {
                var enumType = design.CreateEnum(enumName, stateNames);
                _stateValues = enumType.CILType.GetEnumValues();
                var enumDefault = _stateValues.GetValue(0);
                int j = 0;
                for (int i = 0; i < stateList.Count; i++)
                {
                    if (stateList[i].HasWaitState)
                        stateList[i].WaitStateValue = _stateValues.GetValue(j++);
                    stateList[i].StateValue = _stateValues.GetValue(j++);
                }

                // Create signals for state
                string stateSignalName = prefix + "_state";
                stateSignal = owner.CreateSignalInstance(stateSignalName, enumDefault);
                _nextStateSignal = stateSignal;

                // Implement state joins
                states = new Statement[numStates];
                j = 0;
                for (int i = 0; i < stateList.Count; i++)
                {
                    if (stateList[i].HasWaitState)
                    {
                        var wsb = new DefaultAlgorithmBuilder();
                        ImplementJoin(stateList[i].JP, wsb, stateList[i]);
                        var join = wsb.Complete();
                        states[j++] = join.Body;
                    }
                    states[j++] = stateList[i].Result.Decompiled.Body;
                }
                // Replace ProceedWithState calls with actual states
                for (j = 0; j < states.Length; j++)
                {
                    var orgBody = states[j];
                    var xform = new StateAssigner(this, orgBody);
                    var state = xform.GetAlgorithm();
                    states[j] = state.Body;
                }
            }
            else
            {
                // Implement state joins
                states = new Statement[1];
                // Replace ProceedWithState calls with actual states
                var xform = new StateAssigner(this, stateList[0].Result.Decompiled.Body, true);
                var state = xform.GetAlgorithm();
                states[0] = state.Body;
            }

            var calledMethods = stateList
                .SelectMany(b => b.Result.CalledMethods)
                .Distinct()
                .ToList();
            var calledSyncMethods = calledMethods
                .Where(mci => !mci.Method.IsAsync())
                .ToList();

            var referencedFields = stateList
                .SelectMany(b => b.Result.ReferencedFields)
                .Distinct()
                .ToList();

            var referencedLocals = stateList
                .SelectMany(b => b.Result.Decompiled.LocalVariables)
                .Distinct();

            _coFSMs = DecompileCoFSMs(calledMethods);

            // Extract clock edge
            var predFunc = _context.CurrentProcess.Predicate;
            var predInstRef = LiteralReference.CreateConstant(predFunc.Target);
            var arg = new StackElement(predInstRef, predFunc.Target, EVariability.ExternVariable);
            var edge = _curTempl.GetCallExpression(predFunc.Method, arg).Expr;

            // Synchronous process
            var alg = new DefaultAlgorithmBuilder();
            foreach (var v in referencedLocals)
            {
                alg.DeclareLocal(v);
            }
            alg.If(edge);

            // Co state machines
            foreach (var cofsm in _coFSMs.Order)
            {
                foreach (var argv in cofsm.Arguments)
                    alg.DeclareLocal(argv);
                alg.DeclareLocal(cofsm.DoneVar);
                if (cofsm.ResultVar != null)
                    alg.DeclareLocal(cofsm.ResultVar);

                _curCoFSM = cofsm;
                var weaver = new StateWeaver(this, cofsm.HandlerBody);
                alg.InlineCall(weaver.GetAlgorithm().Body); 
            }

            // Main state machine switch statement
            if (numStates > 1)
            {
                var switchStmt = alg.Switch(
                    SignalRef.Create(stateSignal, SignalRef.EReferencedProperty.Cur));
                {
                    for (int i = 0; i < states.Length; i++)
                    {
                        var stateValue = _stateValues.GetValue(i);
                        alg.Case(LiteralReference.CreateConstant(stateValue));
                        var weaver = new StateWeaver(this, states[i]);
                        alg.InlineCall(weaver.GetAlgorithm().Body);
                        alg.Break(switchStmt);
                        alg.EndCase();
                    }
                }
                alg.EndSwitch();
            }
            else
            {
                var weaver = new StateWeaver(this, states[0]);
                alg.InlineCall(weaver.GetAlgorithm().Body);
            }
            alg.EndIf();
            var syncPS = alg.Complete();
            syncPS.Name = prefix + "$sync";
            myps.Kind = Process.EProcessKind.Triggered;
            myps.Sensitivity = new ISignalOrPortDescriptor[] { ((SignalBase)predFunc.Target).Descriptor };

            return new Result(syncPS, calledSyncMethods, referencedFields);
        }
Ejemplo n.º 4
0
        private CoFSM DecompileToCoFSM(string prefix)
        {
            ImplStyle = EAsyncImplStyle.FSM;
            InjectAttributes(prefix);
            InitializeCFGs();

            CoFSM cofsm = new CoFSM();

            var args = _code.AsyncMethod.GetParameters();
            cofsm.Arguments = new Variable[args.Length];
            _argFields = new Dictionary<string, Variable>();
            for (int i = 0; i < args.Length; i++)
            {
                string name = prefix + "_" + args[i].Name;
                var argv = new Variable(TypeDescriptor.GetTypeOf(_arguments[i]))
                {
                    Name = name
                };
                _argFields[args[i].Name] = argv;
                cofsm.Arguments[i] = argv;
            }

            int numILStates = _stateCFGs.Length;
            var mym = _code as MethodDescriptor;
            cofsm.Method = mym;
            cofsm.Dependencies = new HashSet<Task>();

            // Create result variable and done flag
            cofsm.DoneVar = new Variable(typeof(bool)) {
                Name = prefix + "_$done"
            };
            if (_code.AsyncMethod.ReturnType.IsGenericType &&
                _code.AsyncMethod.ReturnType.GetGenericTypeDefinition().Equals(typeof(Task<>)))
            {
                var resultType = _code.AsyncMethod.ReturnType.GetGenericArguments()[0];
                if (!resultType.Equals(typeof(void)))
                {
                    cofsm.ResultVar = new Variable(resultType)
                    {
                        Name = prefix + "_$result"
                    };

                    var builderType = typeof(AsyncTaskMethodBuilder<>).MakeGenericType(resultType);
                    AttributeInjector.Inject(builderType,
                        new MapToIntrinsicType(Meta.EIntrinsicTypes.IllegalRuntimeType));
                    var aoc1 = builderType.GetMethod("AwaitOnCompleted");
                    var aoc2 = builderType.GetMethod("AwaitUnsafeOnCompleted");
                    var rwc = new AwaitOnCompletedRewriter();
                    AttributeInjector.Inject(aoc1, rwc);
                    AttributeInjector.Inject(aoc2, rwc);
                    var sr = builderType.GetMethod("SetResult");
                    var rwsr = new SetResultRewriter();
                    AttributeInjector.Inject(sr, rwsr);
                    var se = builderType.GetMethod("SetException");
                    var serw = new SetExceptionRewriter();
                    AttributeInjector.Inject(se, serw);
                    AttributeInjector.Inject(builderType, new HideDeclaration());

                    var awaiterType = typeof(TaskAwaiter<>).MakeGenericType(resultType);
                    AttributeInjector.Inject(awaiterType,
                        new MapToIntrinsicType(Meta.EIntrinsicTypes.IllegalRuntimeType));
                    AttributeInjector.Inject(awaiterType.GetMethod("get_IsCompleted"), new RewriteIsCompleted());
                    AttributeInjector.Inject(awaiterType.GetMethod("OnCompleted"), new AwaitOnCompletedRewriter());
                    AttributeInjector.Inject(awaiterType.GetMethod("UnsafeOnCompleted"), new AwaitOnCompletedRewriter());
                    AttributeInjector.Inject(awaiterType.GetMethod("GetResult"), new RewriteGetResult());
                    AttributeInjector.Inject(awaiterType, new HideDeclaration());
                }
            }

            // Decompile state handlers
            _stateInfos = new Dictionary<StateInfo, StateInfo>();
            var decomp = new MSILDecompiler(_code, _stateCFGs[0], _fsmInstance);
            _curTempl = decomp.Template;
            _curTempl.AddAttribute(this);
            _curTempl.DisallowReturnStatements = true;
            _curTempl.DisallowConditionals = true;
            _curTempl.DisallowLoops = true;
            var lvState = _curTempl.ExportLocalVariableState();
            var startSI = new StateInfo(-1);
            foreach (var kvp in _locFields)
                startSI.LVState[kvp.Key] = kvp.Value.Type.GetSampleInstance(ETypeCreationOptions.ForceCreation);
            _stateInfos[startSI] = startSI;
            _curSI = startSI;
            var stateList = new List<StateInfo>();
            stateList.Add(startSI);
            _stateQ = new Queue<StateInfo>();
            _curCoFSM = cofsm;
            startSI.Result = decomp.Decompile();
            while (_stateQ.Any())
            {
                var nextSI = _stateQ.Dequeue();
                _curSI = nextSI.Fork(nextSI.ILState);
                decomp = new MSILDecompiler(_code, _stateCFGs[nextSI.ILState + 1], _fsmInstance);
                _curTempl = decomp.Template;
                _curTempl.AddAttribute(this);
                _curTempl.DisallowReturnStatements = true;
                _curTempl.DisallowConditionals = true;
                _curTempl.DisallowLoops = true;
                _curSI.Result = decomp.Decompile();
                stateList.Add(_curSI);
                _stateInfos[_curSI] = _curSI;
            }

            // Create state active variables
            cofsm.StateActiveVars = new List<Variable>();
            int j = 0;
            for (int i = 0; i < stateList.Count; i++)
            {
                if (stateList[i].HasWaitState)
                {
                    cofsm.StateActiveVars.Add(new Variable(typeof(bool))
                    {
                        Name = prefix + "_$waitStateActive" + i
                    });
                    stateList[i].WaitStateValue = j++;
                }
                cofsm.StateActiveVars.Add(new Variable(typeof(bool))
                {
                    Name = prefix + "_$stateActive" + i
                });
                stateList[i].StateValue = j++;
            }

            int numStates = j;

            // Replace ProceedWithState calls with actual states
            var states = new Statement[numStates];

            j = 0;
            for (int i = 0; i < stateList.Count; i++)
            {
                if (stateList[i].HasWaitState)
                {
                    var wsb = new DefaultAlgorithmBuilder();
                    ImplementJoin(stateList[i].JP, wsb, stateList[i]);
                    //wsb.Call(stateList[i].JoinSpec, new Expression[0]);
                    var join = wsb.Complete();
                    states[j++] = join.Body;
                }
                states[j++] = stateList[i].Result.Decompiled.Body;
            }

            for (j = 0; j < states.Length; j++)
            {
                var orgBody = states[j];
                var xform = new CoStateAssigner(this, cofsm.StateActiveVars, orgBody, j);
                var state = xform.GetAlgorithm();
                states[j] = state.Body;
            }

            var calledMethods = stateList
                .SelectMany(b => b.Result.CalledMethods)
                .Distinct()
                .ToList();
            var calledSyncMethods = calledMethods
                .Where(mci => !mci.Method.IsAsync())
                .ToList();
            cofsm.CalledMethods = calledSyncMethods;

            // State handlers
            var alg = new DefaultAlgorithmBuilder();
            alg.Store(cofsm.DoneVar, LiteralReference.CreateConstant(false));
            for (int i = states.Length - 1; i >= 1; i--)
            {
                var lrsa = (LiteralReference)cofsm.StateActiveVars[i];
                alg.If(lrsa);
                alg.InlineCall(states[i]);
                alg.EndIf();
            }
            var handlerAlg = alg.Complete();
            cofsm.HandlerBody = handlerAlg.Body;
            alg = new DefaultAlgorithmBuilder();
            alg.Store(cofsm.DoneVar, LiteralReference.CreateConstant(false));
            alg.InlineCall(states[0]);
            cofsm.InitialHandler = alg.Complete().Body;

            return cofsm;
        }
Ejemplo n.º 5
0
 public IDecompilationResult DecompileSequential()
 {
     _cfg = MethodCode.Create(_code.Method);
     var targets = StateTargetFinder.FindStateTargets(_cfg);
     var entry = targets[0];
     var entryCFG = MethodCode.Create(_code.Method, entry.StartIndex);
     var decomp = new MSILDecompiler(_code, entryCFG, _fsmInstance);
     decomp.Template.AddAttribute(this);
     decomp.Template.DisallowReturnStatements = true;
     var result = decomp.Decompile();
     return result;
 }
Ejemplo n.º 6
0
        private void DecompileAndEnqueueCallees(CodeDescriptor cd, object instance, object[] arguments, MethodCallInfo mymci = null)
        {
            IPackageOrComponentDescriptor owner = cd.Owner as IPackageOrComponentDescriptor;

            var rmd = cd.Method.GetCustomOrInjectedAttribute<RewriteMethodDefinition>();

            IDecompilationResult result;

            var md = cd as MethodDescriptor;
            var pd = cd as ProcessDescriptor;
            if (pd != null)
                _context.CurrentProcess = pd.Instance;
            else
                _context.CurrentProcess = md.CallingProcess.Instance;

            EVariability[] argVar;
            if (md == null)
                argVar = new EVariability[0];
            else
                argVar = md.ArgVariabilities;
            if (rmd != null)
            {
                result = rmd.Rewrite(_context, cd, instance, arguments);
            }
            else if (cd.Method.IsMoveNext())
            {
                var decomp = new AsyncMethodDecompiler(_context, cd, instance, arguments);
                result = decomp.Decompile();
                cd.Implementation = result.Decompiled;
                cd.GenuineImplementation = result.Decompiled;
            }
            else
            {
                var decomp = new MSILDecompiler(cd, instance, arguments, argVar);
                if (cd is ProcessDescriptor)
                {
                    decomp.Template.DisallowReturnStatements = true;
                }
                decomp.Template.DisallowConditionals = true;
                if (mymci != null)
                    mymci.Inherit(decomp.Template);
                result = decomp.Decompile();
                cd.Implementation = result.Decompiled;
                cd.GenuineImplementation = result.Decompiled;
            }

            foreach (var mci in result.CalledMethods)
            {
                _methodQ.Enqueue(mci);
            }
            foreach (var fri in result.ReferencedFields)
            {
                AnalyzeFieldRef(fri, cd);
            }

            _allMethods.Add(cd);
        }
Ejemplo n.º 7
0
        private void DecompileAndEnqueueCallees(CodeDescriptor cd, object instance, object[] arguments, MethodCallInfo mymci = null)
        {
            IPackageOrComponentDescriptor owner = cd.Owner as IPackageOrComponentDescriptor;

            var rmd = cd.Method.GetCustomOrInjectedAttribute <RewriteMethodDefinition>();

            IDecompilationResult result;

            var md = cd as MethodDescriptor;
            var pd = cd as ProcessDescriptor;

            if (pd != null)
            {
                _context.CurrentProcess = pd.Instance;
            }
            else
            {
                _context.CurrentProcess = md.CallingProcess.Instance;
            }

            EVariability[] argVar;
            if (md == null)
            {
                argVar = new EVariability[0];
            }
            else
            {
                argVar = md.ArgVariabilities;
            }
            if (rmd != null)
            {
                result = rmd.Rewrite(_context, cd, instance, arguments);
            }
            else if (cd.Method.IsMoveNext())
            {
                var decomp = new AsyncMethodDecompiler(_context, cd, instance, arguments);
                result                   = decomp.Decompile();
                cd.Implementation        = result.Decompiled;
                cd.GenuineImplementation = result.Decompiled;
            }
            else
            {
                var decomp = new MSILDecompiler(cd, instance, arguments, argVar);
                if (cd is ProcessDescriptor)
                {
                    decomp.Template.DisallowReturnStatements = true;
                }
                decomp.Template.DisallowConditionals = true;
                if (mymci != null)
                {
                    mymci.Inherit(decomp.Template);
                }
                result                   = decomp.Decompile();
                cd.Implementation        = result.Decompiled;
                cd.GenuineImplementation = result.Decompiled;
            }

            foreach (var mci in result.CalledMethods)
            {
                _methodQ.Enqueue(mci);
            }
            foreach (var fri in result.ReferencedFields)
            {
                AnalyzeFieldRef(fri, cd);
            }

            _allMethods.Add(cd);
        }