예제 #1
0
        public bool PrtPopState(bool isPopStatement)
        {
            Debug.Assert(stateStack.TopOfStack != null);
            //pop stack
            stateStack.PopStackFrame();

            if (stateStack.TopOfStack == null)
            {
                if (isPopStatement)
                {
                    throw new PrtInvalidPopStatement();
                }
                //TODO : Handle the monitor machine case separately for the halt event
                else if (eventValue.IsEqual(PrtValue.HaltEvent))
                {
                    throw new PrtUnhandledEventException();
                }
                else
                {
                    currentStatus = PrtMachineStatus.Halted;
                }
            }

            return(currentStatus == PrtMachineStatus.Halted);
        }
예제 #2
0
        public override void PrtEnqueueEvent(PrtValue e, PrtValue arg, PrtMachine source)
        {
            int numOfStepsTaken = 0;

            // set the currentTrigger and currentPayload fields
            // so that we can reuse the common functions
            currentPayload = arg.Clone();
            currentTrigger = e;

            PrtValue currEventValue;
            PrtFun   currAction;
            bool     hasMoreWork = false;

            try
            {
Start:
                switch (nextSMOperation)
                {
                case PrtNextStatemachineOperation.EntryOperation:
                    goto DoEntry;

                case PrtNextStatemachineOperation.HandleEventOperation:
                    goto DoHandleEvent;
                }

DoEntry:
                if (invertedFunStack.TopOfStack == null)
                {
                    //Trace: entered state
                    if (CurrentState.entryFun.IsAnonFun)
                    {
                        PrtPushFunStackFrame(CurrentState.entryFun, CurrentState.entryFun.CreateLocals(currentPayload));
                    }
                    else
                    {
                        PrtPushFunStackFrame(CurrentState.entryFun, CurrentState.entryFun.CreateLocals());
                    }
                }
                //invoke the function
                invertedFunStack.TopOfStack.fun.Execute(stateImpl, this);
                goto CheckFunLastOperation;

DoAction:
                currAction = PrtFindActionHandler(eventValue);
                if (currAction == PrtCommonFunctions.IgnoreFun)
                {
                    //Trace: Performed ignore action for the event
                    currentTrigger = PrtValue.NullValue;
                    currentPayload = PrtValue.NullValue;
                }
                else
                {
                    if (invertedFunStack.TopOfStack == null)
                    {
                        //Trace: executed the action handler for event
                        PrtPushFunStackFrame(currAction, currAction.CreateLocals(currentPayload));
                    }
                    //invoke the action handler
                    invertedFunStack.TopOfStack.fun.Execute(stateImpl, this);
                }
                goto CheckFunLastOperation;

CheckFunLastOperation:
                switch (continuation.reason)
                {
                case PrtContinuationReason.Goto:
                {
                    stateExitReason = PrtStateExitReason.OnGotoStatement;
                    PrtExecuteExitFunction();
                    goto CheckFunLastOperation;
                }

                case PrtContinuationReason.Raise:
                {
                    nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation;
                    hasMoreWork     = true;
                    goto Finish;
                }

                case PrtContinuationReason.Return:
                {
                    switch (stateExitReason)
                    {
                    case PrtStateExitReason.NotExit:
                    {
                        nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation;
                        hasMoreWork     = false;
                        goto Finish;
                    }

                    case PrtStateExitReason.OnGotoStatement:
                    {
                        PrtChangeState(destOfGoto);
                        nextSMOperation = PrtNextStatemachineOperation.EntryOperation;
                        stateExitReason = PrtStateExitReason.NotExit;
                        hasMoreWork     = true;
                        goto Finish;
                    }

                    case PrtStateExitReason.OnUnhandledEvent:
                    {
                        hasMoreWork     = !PrtPopState(false);
                        nextSMOperation = PrtNextStatemachineOperation.HandleEventOperation;
                        stateExitReason = PrtStateExitReason.NotExit;
                        goto Finish;
                    }

                    case PrtStateExitReason.OnTransition:
                    {
                        stateExitReason = PrtStateExitReason.OnTransitionAfterExit;
                        PrtExecuteTransitionFun(eventValue);
                        goto CheckFunLastOperation;
                    }

                    case PrtStateExitReason.OnTransitionAfterExit:
                    {
                        PrtChangeState(CurrentState.transitions[eventValue].gotoState);
                        hasMoreWork     = true;
                        nextSMOperation = PrtNextStatemachineOperation.EntryOperation;
                        stateExitReason = PrtStateExitReason.NotExit;
                        goto Finish;
                    }

                    default:
                    {
                        Debug.Assert(false, "Unexpected value for exit reason");
                        goto Finish;
                    }
                    }
                }

                default:
                {
                    Debug.Assert(false, "Unexpected value for continuation reason");
                    goto Finish;
                }
                }

DoHandleEvent:
                if (!currentTrigger.IsEqual(PrtValue.NullValue))
                {
                    currEventValue = currentTrigger;
                    currentTrigger = PrtValue.NullValue;
                }
                else
                {
                    currEventValue = eventValue;
                }

                if (PrtIsTransitionPresent(currEventValue))
                {
                    stateExitReason = PrtStateExitReason.OnTransition;
                    eventValue      = currEventValue;
                    PrtExecuteExitFunction();
                    goto CheckFunLastOperation;
                }
                else if (PrtIsActionInstalled(currEventValue))
                {
                    goto DoAction;
                }
                else
                {
                    stateExitReason = PrtStateExitReason.OnUnhandledEvent;
                    eventValue      = currEventValue;
                    PrtExecuteExitFunction();
                    goto CheckFunLastOperation;
                }

Finish:
                if (hasMoreWork)
                {
                    if (numOfStepsTaken > 100000)
                    {
                        throw new PrtInfiniteRaiseLoop("Infinite loop in monitor");
                    }
                    else
                    {
                        numOfStepsTaken++;
                        goto Start;
                    }
                }
                else
                {
                    return;
                }
            }
            catch (PrtException ex)
            {
                stateImpl.Exception = ex;
            }
        }