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