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; }
public void CreateStagedDecoder(IAutoBinder binder, SLVSignal cwSignal, SLSignal clkSignal, bool registered) { var valWordInit = StdLogicVector._0s(_vcf.ValueWordWidth); var rcwSignal = (SLVSignal)binder.GetSignal(EPortUsage.Default, "D1_CW", null, valWordInit); var rcwSignalDesc = rcwSignal.Descriptor; SLVSignal rrcwSignal = null; if (registered) { rrcwSignal = (SLVSignal)binder.GetSignal(EPortUsage.Default, "D2_CW", null, valWordInit); } var syncBuilder = new DefaultAlgorithmBuilder(); syncBuilder.If(clkSignal.ToSignalRef(SignalRef.EReferencedProperty.RisingEdge)); syncBuilder.Store(rcwSignal.ToSignalRef(SignalRef.EReferencedProperty.Next), ((ISignal)cwSignal[_vcf.ValueWordWidth - 1, 0]).ToSignalRef(SignalRef.EReferencedProperty.Cur)); if (registered) { syncBuilder.Store(rrcwSignal.ToSignalRef(SignalRef.EReferencedProperty.Next), rcwSignal.ToSignalRef(SignalRef.EReferencedProperty.Cur)); } foreach (var ms in _strings) { ms.AssembleStagedDecoderSync(binder, syncBuilder, cwSignal, registered); } syncBuilder.EndIf(); var syncFunc = syncBuilder.Complete(); syncFunc.Name = "cwdecode_sync"; binder.CreateProcess(SystemSharp.Components.Process.EProcessKind.Triggered, syncFunc, clkSignal.Descriptor); var combBuilder = new DefaultAlgorithmBuilder(); var sensitivity = new HashSet<ISignalOrPortDescriptor>(); sensitivity.Add(cwSignal.Descriptor); sensitivity.Add(rcwSignalDesc); if (registered) sensitivity.Add(rrcwSignal.Descriptor); foreach (var ms in _strings) { ms.AssembleStagedDecoderComb(combBuilder, registered ? rrcwSignal : rcwSignal, sensitivity, registered); } var combFunc = combBuilder.Complete(); combFunc.Name = "cwdecode_comb"; binder.CreateProcess(SystemSharp.Components.Process.EProcessKind.Triggered, combFunc, sensitivity.ToArray()); }