📄 xvm.cpp
字号:
iJump = TRUE;
break;
case OP_TYPE_STRING:
if ( strcmp ( Op0.pstrStringLiteral, Op1.pstrStringLiteral ) == 0 )
iJump = TRUE;
break;
}
break;
}
// Jump if Not Equal
case INSTR_JNE:
{
switch ( Op0.iType )
{
case OP_TYPE_INT:
if ( Op0.iIntLiteral != Op1.iIntLiteral )
iJump = TRUE;
break;
case OP_TYPE_FLOAT:
if ( Op0.fFloatLiteral != Op1.fFloatLiteral )
iJump = TRUE;
break;
case OP_TYPE_STRING:
if ( strcmp ( Op0.pstrStringLiteral, Op1.pstrStringLiteral ) != 0 )
iJump = TRUE;
break;
}
break;
}
// Jump if Greater
case INSTR_JG:
if ( Op0.iType == OP_TYPE_INT )
{
if ( Op0.iIntLiteral > Op1.iIntLiteral )
iJump = TRUE;
}
else
{
if ( Op0.fFloatLiteral > Op1.fFloatLiteral )
iJump = TRUE;
}
break;
// Jump if Less
case INSTR_JL:
if ( Op0.iType == OP_TYPE_INT )
{
if ( Op0.iIntLiteral < Op1.iIntLiteral )
iJump = TRUE;
}
else
{
if ( Op0.fFloatLiteral < Op1.fFloatLiteral )
iJump = TRUE;
}
break;
// Jump if Greater or Equal
case INSTR_JGE:
if ( Op0.iType == OP_TYPE_INT )
{
if ( Op0.iIntLiteral >= Op1.iIntLiteral )
iJump = TRUE;
}
else
{
if ( Op0.fFloatLiteral >= Op1.fFloatLiteral )
iJump = TRUE;
}
break;
// Jump if Less or Equal
case INSTR_JLE:
if ( Op0.iType == OP_TYPE_INT )
{
if ( Op0.iIntLiteral <= Op1.iIntLiteral )
iJump = TRUE;
}
else
{
if ( Op0.fFloatLiteral <= Op1.fFloatLiteral )
iJump = TRUE;
}
break;
}
// If the comparison evaluated to TRUE, make the jump
if ( iJump )
g_Scripts [ g_iCurrThread ].InstrStream.iCurrInstr = iTargetIndex;
break;
}
// ---- The Stack Interface
case INSTR_PUSH:
{
// Get a local copy of the source operand (operand index 0)
Value Source = ResolveOpValue ( 0 );
// Push the value onto the stack
Push ( g_iCurrThread, Source );
break;
}
case INSTR_POP:
{
// Pop the top of the stack into the destination
* ResolveOpPntr ( 0 ) = Pop ( g_iCurrThread );
break;
}
// ---- The Function Call Interface
case INSTR_CALL:
{
// Get a local copy of the function index
int iFuncIndex = ResolveOpAsFuncIndex ( 0 );
// Advance the instruction pointer so it points to the instruction
// immediately following the call
++ g_Scripts [ g_iCurrThread ].InstrStream.iCurrInstr;
// Call the function
CallFunc ( g_iCurrThread, iFuncIndex );
break;
}
case INSTR_RET:
{
// Get the current function index off the top of the stack and use it to get
// the corresponding function structure
Value FuncIndex = Pop ( g_iCurrThread );
// Check for the presence of a stack base marker
if ( FuncIndex.iType = OP_TYPE_STACK_BASE_MARKER )
iExitExecLoop = TRUE;
// Get the previous function index
Func CurrFunc = GetFunc ( g_iCurrThread, FuncIndex.iFuncIndex );
int iFrameIndex = FuncIndex.iOffsetIndex;
// Read the return address structure from the stack, which is stored one
// index below the local data
Value ReturnAddr = GetStackValue ( g_iCurrThread, g_Scripts [ g_iCurrThread ].Stack.iTopIndex - ( CurrFunc.iLocalDataSize + 1 ) );
// Pop the stack frame along with the return address
PopFrame ( CurrFunc.iStackFrameSize );
// Restore the previous frame index
g_Scripts [ g_iCurrThread ].Stack.iFrameIndex = iFrameIndex;
// Make the jump to the return address
g_Scripts [ g_iCurrThread ].InstrStream.iCurrInstr = ReturnAddr.iInstrIndex;
break;
}
case INSTR_CALLHOST:
{
// Use operand zero to index into the host API call table and get the
// host API function name
Value HostAPICall = ResolveOpValue ( 0 );
int iHostAPICallIndex = HostAPICall.iHostAPICallIndex;
// Get the name of the host API function
char * pstrFuncName = GetHostAPICall ( iHostAPICallIndex );
// Search through the host API until the matching function is found
int iMatchFound = FALSE;
for ( int iHostAPIFuncIndex = 0; iHostAPIFuncIndex < MAX_HOST_API_SIZE; ++ iHostAPIFuncIndex )
{
// Get a pointer to the name of the current host API function
char * pstrCurrHostAPIFunc = g_HostAPI [ iHostAPIFuncIndex ].pstrName;
// If it equals the requested name, it might be a match
if ( strcmp ( pstrFuncName, pstrCurrHostAPIFunc ) == 0 )
{
// Make sure the function is visible to the current thread
int iThreadIndex = g_HostAPI [ iHostAPIFuncIndex ].iThreadIndex;
if ( iThreadIndex == g_iCurrThread || iThreadIndex == XS_GLOBAL_FUNC )
{
iMatchFound = TRUE;
break;
}
}
}
// If a match was found, call the host API funcfion and pass the current
// thread index
if ( iMatchFound )
g_HostAPI [ iHostAPIFuncIndex ].fnFunc ( g_iCurrThread );
break;
}
// ---- Misc
case INSTR_PAUSE:
{
// Get the pause duration
int iPauseDuration = ResolveOpAsInt ( 0 );
// Determine the ending pause time
g_Scripts [ g_iCurrThread ].iPauseEndTime = iCurrTime + iPauseDuration;
// Pause the script
g_Scripts [ g_iCurrThread ].iIsPaused = TRUE;
break;
}
case INSTR_EXIT:
{
// Resolve operand zero to find the exit code
Value ExitCode = ResolveOpValue ( 0 );
// Get it from the integer field
int iExitCode = ExitCode.iIntLiteral;
// Tell the XVM to stop executing the script
g_Scripts [ g_iCurrThread ].iIsRunning = FALSE;
break;
}
}
// If the instruction pointer hasn't been changed by an instruction, increment it
if ( iCurrInstr == g_Scripts [ g_iCurrThread ].InstrStream.iCurrInstr )
++ g_Scripts [ g_iCurrThread ].InstrStream.iCurrInstr;
// If we aren't running indefinitely, check to see if the main timeslice has ended
if ( iTimesliceDur != XS_INFINITE_TIMESLICE )
if ( iCurrTime > iMainTimesliceStartTime + iTimesliceDur )
break;
// Exit the execution loop if the script has terminated
if ( iExitExecLoop )
break;
}
}
/******************************************************************************************
*
* XS_StartScript ()
*
* Starts the execution of a script.
*/
void XS_StartScript ( int iThreadIndex )
{
// Make sure the thread index is valid and active
if ( ! IsThreadActive ( iThreadIndex ) )
return;
// Set the thread's execution flag
g_Scripts [ iThreadIndex ].iIsRunning = TRUE;
// Set the current thread to the script
g_iCurrThread = iThreadIndex;
// Set the activation time for the current thread to get things rolling
g_iCurrThreadActiveTime = GetCurrTime ();
}
/******************************************************************************************
*
* XS_StopScript ()
*
* Stops the execution of a script.
*/
void XS_StopScript ( int iThreadIndex )
{
// Make sure the thread index is valid and active
if ( ! IsThreadActive ( iThreadIndex ) )
return;
// Clear the thread's execution flag
g_Scripts [ iThreadIndex ].iIsRunning = FALSE;
}
/******************************************************************************************
*
* XS_PauseScript ()
*
* Pauses a script for a specified duration.
*/
void XS_PauseScript ( int iThreadIndex, int iDur )
{
// Make sure the thread index is valid and active
if ( ! IsThreadActive ( iThreadIndex ) )
return;
// Set the pause flag
g_Scripts [ iThreadIndex ].iIsPaused = TRUE;
// Set the duration of the pause
g_Scripts [ iThreadIndex ].iPauseEndTime = GetCurrTime () + iDur;
}
/******************************************************************************************
*
* XS_UnpauseScript ()
*
* Unpauses a script.
*/
void XS_UnpauseScript ( int iThreadIndex )
{
// Make sure the thread index is valid and active
if ( ! IsThreadActive ( iThreadIndex ) )
return;
// Clear the pause flag
g_Scripts [ iThreadIndex ]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -