📄 xvm.cpp
字号:
/*
Project.
XVM - The XtremeScript Virtual Machine
Abstract.
An embeddable runtime environment that can load and run multiple scripts concurrently
in a multithreaded environment and provides two way communication with the host
application.
Date Created.
7.31.2002
Author.
Alex Varanese
*/
// ---- Include Files -------------------------------------------------------------------------
#include "xvm.h"
// ---- Constants -----------------------------------------------------------------------------
// ---- Script Loading --------------------------------------------------------------------
#define EXEC_FILE_EXT ".XSE" // Executable file extension
#define XSE_ID_STRING "XSE0" // Used to validate an .XSE executable
#define MAX_THREAD_COUNT 1024 // The maximum number of scripts that
// can be loaded at once. Change this
// to support more or less.
// ---- Operand/Value Types ---------------------------------------------------------------
#define OP_TYPE_NULL -1 // Uninitialized/Null data
#define OP_TYPE_INT 0 // Integer literal value
#define OP_TYPE_FLOAT 1 // Floating-point literal value
#define OP_TYPE_STRING 2 // String literal value
#define OP_TYPE_ABS_STACK_INDEX 3 // Absolute array index
#define OP_TYPE_REL_STACK_INDEX 4 // Relative array index
#define OP_TYPE_INSTR_INDEX 5 // Instruction index
#define OP_TYPE_FUNC_INDEX 6 // Function index
#define OP_TYPE_HOST_API_CALL_INDEX 7 // Host API call index
#define OP_TYPE_REG 8 // Register
#define OP_TYPE_STACK_BASE_MARKER 9 // Marks a stack base
// ---- Instruction Opcodes ---------------------------------------------------------------
#define INSTR_MOV 0
#define INSTR_ADD 1
#define INSTR_SUB 2
#define INSTR_MUL 3
#define INSTR_DIV 4
#define INSTR_MOD 5
#define INSTR_EXP 6
#define INSTR_NEG 7
#define INSTR_INC 8
#define INSTR_DEC 9
#define INSTR_AND 10
#define INSTR_OR 11
#define INSTR_XOR 12
#define INSTR_NOT 13
#define INSTR_SHL 14
#define INSTR_SHR 15
#define INSTR_CONCAT 16
#define INSTR_GETCHAR 17
#define INSTR_SETCHAR 18
#define INSTR_JMP 19
#define INSTR_JE 20
#define INSTR_JNE 21
#define INSTR_JG 22
#define INSTR_JL 23
#define INSTR_JGE 24
#define INSTR_JLE 25
#define INSTR_PUSH 26
#define INSTR_POP 27
#define INSTR_CALL 28
#define INSTR_RET 29
#define INSTR_CALLHOST 30
#define INSTR_PAUSE 31
#define INSTR_EXIT 32
// ---- Stack -----------------------------------------------------------------------------
#define DEF_STACK_SIZE 1024 // The default stack size
// ---- Coercion --------------------------------------------------------------------------
#define MAX_COERCION_STRING_SIZE 64 // The maximum allocated space for a
// string coercion
// ---- Multithreading --------------------------------------------------------------------
#define THREAD_MODE_MULTI 0 // Multithreaded execution
#define THREAD_MODE_SINGLE 1 // Single-threaded execution
#define THREAD_PRIORITY_DUR_LOW 20 // Low-priority thread timeslice
#define THREAD_PRIORITY_DUR_MED 40 // Medium-priority thread timeslice
#define THREAD_PRIORITY_DUR_HIGH 80 // High-priority thread timeslice
// ---- The Host API ----------------------------------------------------------------------
#define MAX_HOST_API_SIZE 1024 // Maximum number of functions in the
// host API
// ---- Functions -------------------------------------------------------------------------
#define MAX_FUNC_NAME_SIZE 256 // Maximum size of a function's name
// ---- Data Structures -----------------------------------------------------------------------
// ---- Runtime Value ---------------------------------------------------------------------
typedef struct _Value // A runtime value
{
int iType; // Type
union // The value
{
int iIntLiteral; // Integer literal
float fFloatLiteral; // Float literal
char * pstrStringLiteral; // String literal
int iStackIndex; // Stack Index
int iInstrIndex; // Instruction index
int iFuncIndex; // Function index
int iHostAPICallIndex; // Host API Call index
int iReg; // Register code
};
int iOffsetIndex; // Index of the offset
}
Value;
// ---- Runtime Stack ---------------------------------------------------------------------
typedef struct _RuntimeStack // A runtime stack
{
Value * pElmnts; // The stack elements
int iSize; // The number of elements in the stack
int iTopIndex; // The top index
int iFrameIndex; // Index of the top of the current
// stack frame.
}
RuntimeStack;
// ---- Functions -------------------------------------------------------------------------
typedef struct _Func // A function
{
int iEntryPoint; // The entry point
int iParamCount; // The parameter count
int iLocalDataSize; // Total size of all local data
int iStackFrameSize; // Total size of the stack frame
char pstrName [ MAX_FUNC_NAME_SIZE + 1 ]; // The function's name
}
Func;
// ---- Instructions ----------------------------------------------------------------------
typedef struct _Instr // An instruction
{
int iOpcode; // The opcode
int iOpCount; // The number of operands
Value * pOpList; // The operand list
}
Instr;
typedef struct _InstrStream // An instruction stream
{
Instr * pInstrs; // The instructions themselves
int iSize; // The number of instructions in the
// stream
int iCurrInstr; // The instruction pointer
}
InstrStream;
// ---- Function Table --------------------------------------------------------------------
typedef struct _FuncTable // A function table
{
Func * pFuncs; // Pointer to the function array
int iSize; // The number of functions in the array
}
FuncTable;
// ---- Host API Call Table ---------------------------------------------------------------
typedef struct _HostAPICallTable // A host API call table
{
char ** ppstrCalls; // Pointer to the call array
int iSize; // The number of calls in the array
}
HostAPICallTable;
// ---- Scripts ---------------------------------------------------------------------------
typedef struct _Script // Encapsulates a full script
{
int iIsActive; // Is this script structure in use?
// Header data
int iGlobalDataSize; // The size of the script's global data
int iIsMainFuncPresent; // Is _Main () present?
int iMainFuncIndex; // _Main ()'s function index
// Runtime tracking
int iIsRunning; // Is the script running?
int iIsPaused; // Is the script currently paused?
int iPauseEndTime; // If so, when should it resume?
// Threading
int iTimesliceDur; // The thread's timeslice duration
// Register file
Value _RetVal; // The _RetVal register
// Script data
InstrStream InstrStream; // The instruction stream
RuntimeStack Stack; // The runtime stack
FuncTable FuncTable; // The function table
HostAPICallTable HostAPICallTable; // The host API call table
}
Script;
// ---- Host API --------------------------------------------------------------------------
typedef struct _HostAPIFunc // Host API function
{
int iIsActive; // Is this slot in use?
int iThreadIndex; // The thread to which this function
// is visible
char * pstrName; // The function name
HostAPIFuncPntr fnFunc; // Pointer to the function definition
}
HostAPIFunc;
// ---- Globals -------------------------------------------------------------------------------
// ---- Scripts ---------------------------------------------------------------------------
Script g_Scripts [ MAX_THREAD_COUNT ]; // The script array
// ---- Threading -------------------------------------------------------------------------
int g_iCurrThreadMode; // The current threading mode
int g_iCurrThread; // The currently running thread
int g_iCurrThreadActiveTime; // The time at which the current thread
// was activated
// ---- The Host API ----------------------------------------------------------------------
HostAPIFunc g_HostAPI [ MAX_HOST_API_SIZE ]; // The host API
// ---- Macros --------------------------------------------------------------------------------
/******************************************************************************************
*
* ResolveStackIndex ()
*
* Resolves a stack index by translating negative indices relative to the top of the
* stack, to positive ones relative to the bottom.
*/
#define ResolveStackIndex( iIndex ) \
\
( iIndex < 0 ? iIndex += g_Scripts [ g_iCurrThread ].Stack.iFrameIndex : iIndex )
/******************************************************************************************
*
* IsValidThreadIndex ()
*
* Returns TRUE if the specified thread index is within the bounds of the array, FALSE
* otherwise.
*/
#define IsValidThreadIndex( iIndex ) \
\
( iIndex < 0 || iIndex > MAX_THREAD_COUNT ? FALSE : TRUE )
/******************************************************************************************
*
* IsThreadActive ()
*
* Returns TRUE if the specified thread is both a valid index and active, FALSE otherwise.
*/
#define IsThreadActive( iIndex ) \
\
( IsValidThreadIndex ( iIndex ) && g_Scripts [ iIndex ].iIsActive ? TRUE : FALSE )
// ---- Function Prototypes -------------------------------------------------------------------
// ---- Operand Interface -----------------------------------------------------------------
int CoerceValueToInt ( Value Val );
float CoerceValueToFloat ( Value Val );
char * CoerceValueToString ( Value Val );
void CopyValue ( Value * pDest, Value Source );
int GetOpType ( int iOpIndex );
int ResolveOpStackIndex ( int iOpIndex );
Value ResolveOpValue ( int iOpIndex );
int ResolveOpType ( int iOpIndex );
int ResolveOpAsInt ( int iOpIndex );
float ResolveOpAsFloat ( int iOpIndex );
char * ResolveOpAsString ( int iOpIndex );
int ResolveOpAsInstrIndex ( int iOpIndex );
int ResolveOpAsFuncIndex ( int iOpIndex );
char * ResolveOpAsHostAPICall ( int iOpIndex );
Value * ResolveOpPntr ( int iOpIndex );
// ---- Runtime Stack Interface -----------------------------------------------------------
Value GetStackValue ( int iThreadIndex, int iIndex );
void SetStackValue ( int iThreadIndex, int iIndex, Value Val );
void Push ( int iThreadIndex, Value Val );
Value Pop ( int iThreadIndex );
void PushFrame ( int iThreadIndex, int iSize );
void PopFrame ( int iSize );
// ---- Function Table Interface ----------------------------------------------------------
Func GetFunc ( int iThreadIndex, int iIndex );
// ---- Host API Call Table Interface -----------------------------------------------------
char * GetHostAPICall ( int iIndex );
// ---- Time Abstraction ------------------------------------------------------------------
int GetCurrTime ();
// ---- Functions -------------------------------------------------------------------------
void CallFunc ( int iThreadIndex, int iIndex );
// ---- Functions -----------------------------------------------------------------------------
/******************************************************************************************
*
* XS_Init ()
*
* Initializes the runtime environment.
*/
void XS_Init ()
{
// ---- Initialize the script array
for ( int iCurrScriptIndex = 0; iCurrScriptIndex < MAX_THREAD_COUNT; ++ iCurrScriptIndex )
{
g_Scripts [ iCurrScriptIndex ].iIsActive = FALSE;
g_Scripts [ iCurrScriptIndex ].iIsRunning = FALSE;
g_Scripts [ iCurrScriptIndex ].iIsMainFuncPresent = FALSE;
g_Scripts [ iCurrScriptIndex ].iIsPaused = FALSE;
g_Scripts [ iCurrScriptIndex ].InstrStream.pInstrs = NULL;
g_Scripts [ iCurrScriptIndex ].Stack.pElmnts = NULL;
g_Scripts [ iCurrScriptIndex ].FuncTable.pFuncs = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -