void execStdSetState (void) { unsigned long stateHandle = ABLi_popInteger(); if (stateHandle > 0) { SymTableNodePtr stateFunction = ModuleRegistry[CurFSM->getHandle()].stateHandles[stateHandle].state; CurFSM->setPrevState(CurFSM->getState()); CurFSM->setState(stateFunction); sprintf(SetStateDebugStr, "%s:%s, line %d", CurFSM->getFileName(), stateFunction->name, execLineNumber); NewStateSet = true; } }
void execute(SymTableNodePtr routineIdPtr) { SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr; CurRoutineIdPtr = routineIdPtr; routineEntry(routineIdPtr); //---------------------------------------------------- // Now, search this module for the function we want... if(CallModuleInit) { CallModuleInit = false; SymTableNodePtr initFunctionIdPtr = searchSymTable("init", ModuleRegistry[CurModule->getHandle()].moduleIdPtr->defn.info.routine.localSymTable); if(initFunctionIdPtr) { execRoutineCall(initFunctionIdPtr, false); //------------------------------------------------------------------------- // Since we're calling the function directly, we need to compensate for the // codeSegmentPtr being incremented by 1 in the normal execRoutineCall... codeSegmentPtr--; } } if(routineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM) { NewStateSet = true; static char stateList[60][256]; strcpy(SetStateDebugStr, "--"); while(NewStateSet) { NumStateTransitions++; sprintf(stateList[NumStateTransitions], "%s (%s)", CurModule->getState()->name, SetStateDebugStr); if(NumStateTransitions == 50) { UserFile* userFile = UserFile::getNewFile(); char errStr[512]; if(userFile) { int32_t err = userFile->open("endless.log"); if(!err) { //char s[1024]; //sprintf(s, "Current Date: %s\n", GetTime()); //userFile->write(s); userFile->write(ModuleRegistry[CurModule->getHandle()].fileName); for(size_t i = 1; i < 51; i++) userFile->write(stateList[i]); userFile->write(" "); if(ABLEndlessStateCallback) (*ABLEndlessStateCallback)(userFile); userFile->close(); } } sprintf(errStr, " ABL endless state loop in %s [%s:%s] ", ModuleRegistry[CurModule->getHandle()].fileName, CurModule->getState()->name, CurModule->getPrevState()->name); #if 0 ABL_Fatal(NumStateTransitions, errStr); #else NewStateSet = false; #endif } else { NewStateSet = false; SymTableNodePtr curState = CurModule->getState(); if(!curState) ABL_Fatal(0, " ABL.execute: nullptr state in FSM "); execRoutineCall(curState, false); codeSegmentPtr--; } //--------------------------------------------- // In case we exited with a return statement... ExitWithReturn = false; ExitFromTacOrder = false; } } else { getCodeToken(); execStatement(); //--------------------------------------------- // In case we exited with a return statement... ExitWithReturn = false; ExitFromTacOrder = false; } routineExit(routineIdPtr); CurRoutineIdPtr = thisRoutineIdPtr; }
TypePtr execDeclaredRoutineCall(SymTableNodePtr routineIdPtr, bool skipOrder) { if(skipOrder) { StackItemPtr curStackFrameBase = tos; //---------------------------------------- // Push parameter values onto the stack... getCodeToken(); if(codeToken == TKN_LPAREN) { execActualParams(routineIdPtr); getCodeToken(); } getCodeToken(); tos = curStackFrameBase; pushInteger(1); return((TypePtr)(routineIdPtr->typePtr)); } int32_t oldLevel = level; // level of caller int32_t newLevel = routineIdPtr->level + 1; // level of callee CallStackLevel++; //------------------------------------------- // First, set up the stack frame of callee... StackItemPtr newStackFrameBasePtr = tos + 1; bool isLibraryCall = (routineIdPtr->library && (routineIdPtr->library != CurRoutineIdPtr->library)); if(isLibraryCall) pushStackFrameHeader(-1, -1); else pushStackFrameHeader(oldLevel, newLevel); //---------------------------------------- // Push parameter values onto the stack... getCodeToken(); if(codeToken == TKN_LPAREN) { execActualParams(routineIdPtr); getCodeToken(); } //------------------------------------------------- // Set the return address in the new stack frame... level = newLevel; stackFrameBasePtr = newStackFrameBasePtr; StackFrameHeaderPtr headerPtr = (StackFrameHeaderPtr)stackFrameBasePtr; headerPtr->returnAddress.address = codeSegmentPtr - 1; //--------------------------------------------------------- // If we're calling a library function, we need to set some // module-specific info... ABLModulePtr PrevModule = nullptr; if(isLibraryCall) { PrevModule = CurModule; CurModule = routineIdPtr->library; CurModuleHandle = CurModule->getHandle(); if(debugger) debugger->setModule(CurModule); StaticDataPtr = CurModule->getStaticData(); CallModuleInit = !CurModule->getInitCalled(); CurModule->setInitCalled(true); // routineEntry(ModuleRegistry[CurModule->getHandle()].moduleIdPtr); } if(ProfileLog) { int32_t functionStartTime = ABLGetTimeCallback(); execute(routineIdPtr); int32_t functionExecTime = ABLGetTimeCallback() - functionStartTime; if(functionExecTime > ProfileLogFunctionTimeLimit) { char s[512]; sprintf_s(s, _countof(s), "[%08d] ", NumExecutions); for(size_t i = 0; i < CallStackLevel; i++) strcat(s, " "); char s1[512]; sprintf_s(s1, _countof(s1), "%s (%d)\n", routineIdPtr->name, functionExecTime); strcat(s, s1); ABL_AddToProfileLog(s); } } else execute(routineIdPtr); //---------------------------------------------------------------- // If we're calling a library function, reset some module-specific // info... if(isLibraryCall) { // routineExit(ModuleRegistry[CurModule->getHandle()].moduleIdPtr); CurModule = PrevModule; CurModuleHandle = CurModule->getHandle(); if(debugger) debugger->setModule(CurModule); StaticDataPtr = CurModule->getStaticData(); } //------------------------------------------------------- // Return from the callee, and grab the first token after // the return... level = oldLevel; getCodeToken(); CallStackLevel--; return((TypePtr)(routineIdPtr->typePtr)); }