2007-06-28 10:47:08 -07:00
/*
* Interp . c
*
* Execute the compiled version of a script
*
*/
/* Control the execution trace printf's */
# define DEBUG_GROUP0
2006-06-02 12:34:58 -07:00
# include "lib/framework/frame.h"
2007-06-28 10:47:08 -07:00
# include "interp.h"
# include "stack.h"
# include "codeprint.h"
# include "script.h"
2006-08-22 07:28:49 -07:00
# include "event.h" //needed for eventGetEventID()
2007-06-28 10:47:08 -07:00
// the maximum number of instructions to execute before assuming
// an infinite loop
# define INTERP_MAXINSTRUCTIONS 100000
2006-09-19 09:30:50 -07:00
typedef struct
{
UDWORD CallerIndex ;
2006-11-16 06:30:29 -08:00
INTERP_VAL * ReturnAddress ;
2006-09-19 09:30:50 -07:00
} ReturnAddressStack_t ;
/**
* Reset the return address stack
*/
static inline void retStackReset ( void ) ;
/**
* Check whether the return address stack is empty
*
* \ return True when empty , false otherwise
*/
static inline BOOL retStackIsEmpty ( void ) ;
2006-08-19 06:26:11 -07:00
2006-09-19 09:30:50 -07:00
/**
* Check whether the return address stack is full
*
* \ return True when full , false otherwise
*/
static inline BOOL retStackIsFull ( void ) ;
/**
* Push a new address / event pair on the return address stack
*
* \ param CallerIndex Index of the calling function
* \ param ReturnAddress Address to return to
* \ return False on failure ( stack full )
*/
2006-11-16 06:30:29 -08:00
static BOOL retStackPush ( UDWORD CallerIndex , INTERP_VAL * ReturnAddress ) ;
2006-09-19 09:30:50 -07:00
/**
* Pop an address / event pair from the return address stack
*
* \ param CallerIndex Index of the calling function
* \ param ReturnAddress Address to return to
* \ return False on failure ( stack empty )
*/
2006-11-16 06:30:29 -08:00
static BOOL retStackPop ( UDWORD * CallerIndex , INTERP_VAL * * ReturnAddress ) ;
2006-08-19 06:26:11 -07:00
2007-06-28 10:47:08 -07:00
/* The size of each opcode */
SDWORD aOpSize [ ] =
{
2 , // OP_PUSH | type, value
2 , // OP_PUSHREF | type, value
1 , // OP_POP
1 , // OP_PUSHGLOBAL | var_num
1 , // OP_POPGLOBAL | var_num
1 , // OP_PUSHARRAYGLOBAL | array_dimensions | array_base
1 , // OP_POPARRAYGLOBAL | array_dimensions | array_base
2006-09-19 09:30:50 -07:00
2 , // OP_CALL | func_pointer
2 , // OP_VARCALL | func_pointer
2007-06-28 10:47:08 -07:00
1 , // OP_JUMP | offset
1 , // OP_JUMPTRUE | offset
1 , // OP_JUMPFALSE | offset
1 , // OP_BINARYOP | secondary op
1 , // OP_UNARYOP | secondary op
1 , // OP_EXIT
1 , // OP_PAUSE
2006-09-19 09:30:50 -07:00
- 1 , // OP_ADD
- 1 , // OP_SUB
- 1 , // OP_MUL
- 1 , // OP_DIV
- 1 , // OP_NEG
- 1 , // OP_AND
- 1 , // OP_OR
- 1 , // OP_NOT
2006-11-16 06:30:29 -08:00
- 1 , // OP_CONC
2006-09-19 09:30:50 -07:00
- 1 , // OP_EQUAL
- 1 , // OP_NOTEQUAL
- 1 , // OP_GREATEREQUAL
- 1 , // OP_LESSEQUAL
- 1 , // OP_GREATER
- 1 , // OP_LESS
2 , // OP_FUNC | func_pointer
1 , // OP_POPLOCAL
1 , // OP_PUSHLOCAL
2006-11-16 06:30:29 -08:00
2006-09-19 09:30:50 -07:00
2 , // OP_PUSHLOCALREF
2006-11-16 06:30:29 -08:00
1 , //OP_TO_FLOAT
1 , //OP_TO_INT
2007-06-28 10:47:08 -07:00
} ;
/* The type equivalence table */
static TYPE_EQUIV * asInterpTypeEquiv ;
// whether the interpreter is running
static BOOL bInterpRunning = FALSE ;
/* Whether to output trace information */
BOOL interpTrace ;
/* Print out trace info if tracing is turned on */
# define TRCPRINTF(x) \
if ( interpTrace ) \
2006-11-02 12:55:19 -08:00
debug ( LOG_NEVER , ( # x ) )
2007-06-28 10:47:08 -07:00
# define TRCPRINTVAL(x) \
if ( interpTrace ) \
cpPrintVal ( x )
# define TRCPRINTMATHSOP(x) \
if ( interpTrace ) \
cpPrintMathsOp ( x )
# define TRCPRINTSTACKTOP() \
if ( interpTrace ) \
stackPrintTop ( )
# define TRCPRINTFUNC(x) \
if ( interpTrace ) \
cpPrintFunc ( x )
# define TRCPRINTVARFUNC(x, data) \
if ( interpTrace ) \
cpPrintVarFunc ( x , data )
// TRUE if the interpreter is currently running
BOOL interpProcessorActive ( void )
{
return bInterpRunning ;
}
/* Find the value store for a global variable */
2006-10-31 12:22:01 -08:00
static inline INTERP_VAL * interpGetVarData ( VAL_CHUNK * psGlobals , UDWORD index )
2007-06-28 10:47:08 -07:00
{
VAL_CHUNK * psChunk ;
psChunk = psGlobals ;
while ( index > = CONTEXT_VALS )
{
index - = CONTEXT_VALS ;
psChunk = psChunk - > psNext ;
}
return psChunk - > asVals + index ;
}
// get the array data for an array operation
2006-11-16 06:30:29 -08:00
static BOOL interpGetArrayVarData ( INTERP_VAL * * pip , VAL_CHUNK * psGlobals , SCRIPT_CODE * psProg , INTERP_VAL * * ppsVal )
2007-06-28 10:47:08 -07:00
{
SDWORD i , dimensions , vals [ VAR_MAX_DIMENSIONS ] ;
UBYTE * elements ; //[VAR_MAX_DIMENSIONS]
SDWORD size , val ; //, elementDWords;
// UBYTE *pElem;
2006-11-16 06:30:29 -08:00
INTERP_VAL * InstrPointer = * pip ;
2007-06-28 10:47:08 -07:00
UDWORD base , index ;
// get the base index of the array
2006-11-16 06:30:29 -08:00
base = InstrPointer - > v . ival & ARRAY_BASE_MASK ;
2007-06-28 10:47:08 -07:00
// get the number of dimensions
2006-11-16 06:30:29 -08:00
dimensions = ( InstrPointer - > v . ival & ARRAY_DIMENSION_MASK ) > > ARRAY_DIMENSION_SHIFT ;
2007-06-28 10:47:08 -07:00
if ( base > = psProg - > numArrays )
{
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE ,
" interpGetArrayVarData: array base index out of range " ) ;
2007-06-28 10:47:08 -07:00
return FALSE ;
}
if ( dimensions ! = psProg - > psArrayInfo [ base ] . dimensions )
{
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE ,
" interpGetArrayVarData: dimensions do not match " ) ;
2007-06-28 10:47:08 -07:00
return FALSE ;
}
// get the number of elements for each dimension
elements = psProg - > psArrayInfo [ base ] . elements ;
/* pElem = (UBYTE *) (ip + 1);
for ( i = 0 ; i < dimensions ; i + = 1 )
{
elements [ i ] = * pElem ;
pElem + = 1 ;
} */
// calculate the index of the array element
size = 1 ;
index = 0 ;
for ( i = dimensions - 1 ; i > = 0 ; i - = 1 )
{
if ( ! stackPopParams ( 1 , VAL_INT , & val ) )
{
return FALSE ;
}
if ( ( val < 0 ) | | ( val > = elements [ i ] ) )
{
2006-10-08 01:06:46 -07:00
ASSERT ( FALSE , " interpGetArrayVarData: Array index for dimension %d out of range (passed index = %d, max index = %d) " , i , val , elements [ i ] ) ;
2007-06-28 10:47:08 -07:00
return FALSE ;
}
index + = val * size ;
size * = psProg - > psArrayInfo [ base ] . elements [ i ] ;
vals [ i ] = val ;
}
// print out the debug trace
if ( interpTrace )
{
2006-08-22 07:28:49 -07:00
debug ( LOG_NEVER , " %d-> " , base ) ;
2007-06-28 10:47:08 -07:00
for ( i = 0 ; i < dimensions ; i + = 1 )
{
2006-08-22 07:28:49 -07:00
debug ( LOG_NEVER , " [%d/%d] " , vals [ i ] , elements [ i ] ) ;
2007-06-28 10:47:08 -07:00
}
2006-08-22 07:28:49 -07:00
debug ( LOG_NEVER , " (%d) " , index ) ;
2007-06-28 10:47:08 -07:00
}
// check the index is valid
if ( index > psProg - > arraySize )
{
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpGetArrayVarData: Array indexes out of variable space " ) ;
2007-06-28 10:47:08 -07:00
return FALSE ;
}
// get the variable data
* ppsVal = interpGetVarData ( psGlobals , psProg - > psArrayInfo [ base ] . base + index ) ;
// calculate the number of DWORDs needed to store the number of elements for each dimension of the array
// elementDWords = (dimensions - 1)/4 + 1;
2006-11-16 06:30:29 -08:00
// update the instruction pointer
2007-06-28 10:47:08 -07:00
* pip + = 1 ; // + elementDWords;
return TRUE ;
}
// Initialise the interpreter
BOOL interpInitialise ( void )
{
asInterpTypeEquiv = NULL ;
return TRUE ;
}
/* Run a compiled script */
BOOL interpRunScript ( SCRIPT_CONTEXT * psContext , INTERP_RUNTYPE runType , UDWORD index , UDWORD offset )
{
2006-11-16 06:30:29 -08:00
SDWORD data ;
OPCODE opcode ;
INTERP_VAL sVal , * psVar , * InstrPointer ;
2007-06-28 10:47:08 -07:00
VAL_CHUNK * psGlobals ;
2006-11-06 13:58:13 -08:00
UDWORD numGlobals = 0 ;
2006-11-16 06:30:29 -08:00
INTERP_VAL * pCodeStart , * pCodeEnd , * pCodeBase ;
2006-11-06 13:58:13 -08:00
SCRIPT_FUNC scriptFunc = 0 ;
SCRIPT_VARFUNC scriptVarFunc = 0 ;
2007-06-28 10:47:08 -07:00
SCRIPT_CODE * psProg ;
SDWORD instructionCount = 0 ;
2006-11-06 13:58:13 -08:00
UDWORD CurEvent = 0 ;
BOOL bStop = FALSE , bEvent = FALSE ;
SDWORD callDepth = 0 ;
2006-11-03 13:35:50 -08:00
const char * pTrigLab , * pEventLab ;
2006-11-17 03:25:03 -08:00
BOOL bTraceOn = FALSE ; //enable to debug function/event calls
2006-08-12 03:02:59 -07:00
2006-08-23 05:58:48 -07:00
ASSERT ( PTRVALID ( psContext , sizeof ( SCRIPT_CONTEXT ) ) ,
" interpRunScript: invalid context pointer " ) ;
2006-11-16 06:30:29 -08:00
psProg = psContext - > psCode ;
2006-08-23 05:58:48 -07:00
ASSERT ( PTRVALID ( psProg , sizeof ( SCRIPT_CODE ) ) ,
" interpRunScript: invalid script code pointer " ) ;
2007-06-28 10:47:08 -07:00
if ( bInterpRunning )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: interpreter already running "
" - callback being called from within a script function? " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE ,
2007-06-28 10:47:08 -07:00
" interpRunScript: interpreter already running "
2006-08-23 05:58:48 -07:00
" - callback being called from within a script function? " ) ;
2007-06-28 10:47:08 -07:00
goto exit_with_error ;
}
// note that the interpreter is running to stop recursive script calls
bInterpRunning = TRUE ;
// Reset the stack in case another script messed up
stackReset ( ) ;
2006-08-12 03:02:59 -07:00
//reset return stack
retStackReset ( ) ;
2007-06-28 10:47:08 -07:00
// Turn off tracing initially
interpTrace = FALSE ;
/* Get the global variables */
numGlobals = psProg - > numGlobals ;
psGlobals = psContext - > psGlobals ;
2006-08-15 11:38:51 -07:00
bEvent = FALSE ;
2007-06-28 10:47:08 -07:00
// Find the code range
switch ( runType )
{
case IRT_TRIGGER :
if ( index > psProg - > numTriggers )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: trigger index out of range " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: trigger index out of range " ) ;
2007-06-28 10:47:08 -07:00
return FALSE ;
}
pCodeBase = psProg - > pCode + psProg - > pTriggerTab [ index ] ;
pCodeStart = pCodeBase ;
pCodeEnd = psProg - > pCode + psProg - > pTriggerTab [ index + 1 ] ;
2006-11-16 06:30:29 -08:00
// find the debug info for the trigger
strcpy ( last_called_script_event , eventGetTriggerID ( psProg , index ) ) ;
2006-11-17 03:25:03 -08:00
if ( bTraceOn )
debug ( LOG_SCRIPT , " Trigger: %s " , last_called_script_event ) ;
2006-11-16 06:30:29 -08:00
2007-06-28 10:47:08 -07:00
break ;
case IRT_EVENT :
if ( index > psProg - > numEvents )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: trigger index out of range " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: trigger index out of range " ) ;
2007-06-28 10:47:08 -07:00
return FALSE ;
}
pCodeBase = psProg - > pCode + psProg - > pEventTab [ index ] ;
2006-08-21 14:20:17 -07:00
pCodeStart = pCodeBase + offset ; //offset only used for pause() script function
2007-06-28 10:47:08 -07:00
pCodeEnd = psProg - > pCode + psProg - > pEventTab [ index + 1 ] ;
2006-08-15 11:38:51 -07:00
bEvent = TRUE ; //remember it's an event
2006-11-16 06:30:29 -08:00
// remember last called event/function
strcpy ( last_called_script_event , eventGetEventID ( psProg , index ) ) ;
2006-11-17 03:25:03 -08:00
if ( bTraceOn )
debug ( LOG_SCRIPT , " Original event name: %s " , last_called_script_event ) ;
2006-11-16 06:30:29 -08:00
2007-06-28 10:47:08 -07:00
break ;
default :
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: unknown run type " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: unknown run type " ) ;
2007-06-28 10:47:08 -07:00
return FALSE ;
}
// Get the first opcode
2006-09-19 09:30:50 -07:00
InstrPointer = pCodeStart ;
2006-11-16 06:30:29 -08:00
/* Make sure we start with an opcode */
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE | | InstrPointer - > type = = VAL_OPCODE ,
" Expected an opcode at the beginning of the interpreting process (type=%d) " , InstrPointer - > type ) ;
//opcode = InstrPointer->v.ival >> OPCODE_SHIFT;
2007-06-28 10:47:08 -07:00
instructionCount = 0 ;
2006-08-12 03:02:59 -07:00
CurEvent = index ;
bStop = FALSE ;
2007-06-28 10:47:08 -07:00
2006-08-12 03:02:59 -07:00
while ( ! bStop )
{
// Run the code
2006-09-19 09:30:50 -07:00
if ( InstrPointer < pCodeEnd ) // && opcode != OP_EXIT)
2007-06-28 10:47:08 -07:00
{
2006-08-12 03:02:59 -07:00
if ( instructionCount > INTERP_MAXINSTRUCTIONS )
2007-06-28 10:47:08 -07:00
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: max instruction count exceeded - infinite loop ? " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE ,
" interpRunScript: max instruction count exceeded - infinite loop ? " ) ;
2007-06-28 10:47:08 -07:00
goto exit_with_error ;
}
2006-11-16 06:30:29 -08:00
instructionCount + + ;
2006-08-12 03:02:59 -07:00
2006-09-19 09:30:50 -07:00
TRCPRINTF ( ( " %-6d " , InstrPointer - psProg - > pCode ) ) ;
2006-11-17 03:25:03 -08:00
opcode = ( OPCODE ) ( InstrPointer - > v . ival > > OPCODE_SHIFT ) ; //get opcode
data = ( SDWORD ) ( InstrPointer - > v . ival & OPCODE_DATAMASK ) ; //get data - only used with packed opcodes
2006-08-12 03:02:59 -07:00
switch ( opcode )
2007-06-28 10:47:08 -07:00
{
2006-08-12 03:02:59 -07:00
/* Custom function call */
case OP_FUNC :
2006-08-15 11:38:51 -07:00
//debug( LOG_SCRIPT, "-OP_FUNC" );
//debug( LOG_SCRIPT, "OP_FUNC: remember event %d, ip=%d", CurEvent, (ip + 2) );
2006-11-16 06:30:29 -08:00
2006-09-19 09:30:50 -07:00
if ( ! retStackPush ( CurEvent , ( InstrPointer + aOpSize [ opcode ] ) ) ) //Remember where to jump back later
2006-08-12 03:02:59 -07:00
{
2006-09-19 09:30:50 -07:00
debug ( LOG_ERROR , " interpRunScript() - retStackPush() failed. " ) ;
2006-08-12 03:02:59 -07:00
return FALSE ;
}
2006-11-16 06:30:29 -08:00
ASSERT ( ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > type = = VAL_EVENT , " wrong value type passed for OP_FUNC: %d " , ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > type ) ;
CurEvent = ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > v . ival ; //Current event = event to jump to
2006-08-15 11:38:51 -07:00
2006-08-12 03:02:59 -07:00
if ( CurEvent > psProg - > numEvents )
{
debug ( LOG_ERROR , " interpRunScript: trigger index out of range " ) ;
2006-11-16 06:30:29 -08:00
goto exit_with_error ;
2006-08-12 03:02:59 -07:00
}
2006-11-16 06:30:29 -08:00
//Set new code execution boundaries
2006-08-12 03:02:59 -07:00
//----------------------------------
pCodeBase = psProg - > pCode + psProg - > pEventTab [ CurEvent ] ;
pCodeStart = pCodeBase ;
pCodeEnd = psProg - > pCode + psProg - > pEventTab [ CurEvent + 1 ] ;
2006-09-19 09:30:50 -07:00
InstrPointer = pCodeStart ; //Start at the beginning of the new event
2006-08-12 03:02:59 -07:00
2006-11-16 06:30:29 -08:00
//remember last called event/index
strcpy ( last_called_script_event , eventGetEventID ( psProg , CurEvent ) ) ;
2006-11-17 03:25:03 -08:00
if ( bTraceOn )
debug ( LOG_SCRIPT , " Called: '%s' " , last_called_script_event ) ;
2006-08-15 11:38:51 -07:00
//debug( LOG_SCRIPT, "-OP_FUNC: jumped to event %d; ip=%d, numLocalVars: %d", CurEvent, ip, psContext->psCode->numLocalVars[CurEvent] );
//debug( LOG_SCRIPT, "-END OP_FUNC" );
2006-08-12 03:02:59 -07:00
break ;
2006-08-15 11:38:51 -07:00
//handle local variables
case OP_PUSHLOCAL :
//debug( LOG_SCRIPT, "OP_PUSHLOCAL");
//debug( LOG_SCRIPT, "OP_PUSHLOCAL, (CurEvent=%d, data =%d) num loc vars: %d; pushing: %d", CurEvent, data, psContext->psCode->numLocalVars[CurEvent], psContext->psCode->ppsLocalVarVal[CurEvent][data].v.ival);
2006-08-22 07:28:49 -07:00
2006-08-15 11:38:51 -07:00
if ( data > = psContext - > psCode - > numLocalVars [ CurEvent ] )
{
debug ( LOG_ERROR , " interpRunScript: OP_PUSHLOCAL: variable index out of range " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: OP_PUSHLOCAL: variable index out of range " ) ;
2006-08-15 11:38:51 -07:00
goto exit_with_error ;
}
//debug( LOG_SCRIPT, "OP_PUSHLOCAL 2");
//debug(LOG_SCRIPT, "OP_PUSHLOCAL type: %d", psContext->psCode->ppsLocalVarVal[CurEvent][data].type);
2006-08-22 07:28:49 -07:00
2006-08-15 11:38:51 -07:00
if ( ! stackPush ( & ( psContext - > psCode - > ppsLocalVarVal [ CurEvent ] [ data ] ) ) )
{
debug ( LOG_ERROR , " interpRunScript: OP_PUSHLOCAL: push failed " ) ;
goto exit_with_error ;
}
//debug( LOG_SCRIPT, "OP_PUSHLOCAL 3");
2006-08-22 07:28:49 -07:00
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-15 11:38:51 -07:00
break ;
case OP_POPLOCAL :
2006-08-22 07:28:49 -07:00
2006-08-15 11:38:51 -07:00
//debug( LOG_SCRIPT, "OP_POPLOCAL, event index: '%d', data: '%d'", CurEvent, data);
//debug( LOG_SCRIPT, "OP_POPLOCAL, numLocalVars: '%d'", psContext->psCode->numLocalVars[CurEvent]);
if ( data > = psContext - > psCode - > numLocalVars [ CurEvent ] )
{
debug ( LOG_ERROR , " interpRunScript: OP_POPLOCAL: variable index out of range " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: variable index out of range " ) ;
2006-08-15 11:38:51 -07:00
goto exit_with_error ;
}
//debug( LOG_SCRIPT, "OP_POPLOCAL 2");
//DbgMsg("OP_POPLOCAL type: %d, CurEvent=%d, data=%d", psContext->psCode->ppsLocalVarVal[CurEvent][data].type, CurEvent, data);
if ( ! stackPopType ( & ( psContext - > psCode - > ppsLocalVarVal [ CurEvent ] [ data ] ) ) )
{
debug ( LOG_ERROR , " interpRunScript: OP_POPLOCAL: pop failed " ) ;
goto exit_with_error ;
}
//debug(LOG_SCRIPT, "OP_POPLOCAL: type=%d, val=%d", psContext->psCode->ppsLocalVarVal[CurEvent][data].type, psContext->psCode->ppsLocalVarVal[CurEvent][data].v.ival);
//debug( LOG_SCRIPT, "OP_POPLOCAL 3");
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-15 11:38:51 -07:00
break ;
case OP_PUSHLOCALREF :
// The type of the variable is stored in with the opcode
2006-11-16 06:30:29 -08:00
sVal . type = ( INTERP_TYPE ) ( InstrPointer - > v . ival & OPCODE_DATAMASK ) ;
ASSERT ( ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > type = = VAL_INT ,
" wrong value type passed for OP_PUSHLOCALREF: %d " , ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > type ) ;
2006-08-15 11:38:51 -07:00
/* get local var index */
2006-11-16 06:30:29 -08:00
data = ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > v . ival ;
2006-08-15 11:38:51 -07:00
if ( data > = psContext - > psCode - > numLocalVars [ CurEvent ] )
{
debug ( LOG_ERROR , " interpRunScript: OP_PUSHLOCALREF: variable index out of range " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: OP_PUSHLOCALREF: variable index out of range " ) ;
2006-08-15 11:38:51 -07:00
goto exit_with_error ;
}
/* get local variable */
psVar = & ( psContext - > psCode - > ppsLocalVarVal [ CurEvent ] [ data ] ) ;
2006-11-16 06:30:29 -08:00
//TODO: fix
2006-08-15 11:38:51 -07:00
sVal . v . oval = & ( psVar - > v . ival ) ;
TRCPRINTF ( ( " PUSHREF " ) ) ;
TRCPRINTVAL ( & sVal ) ;
TRCPRINTF ( ( " \n " ) ) ;
if ( ! stackPush ( & sVal ) )
{
debug ( LOG_ERROR , " interpRunScript: OP_PUSHLOCALREF: push failed " ) ;
goto exit_with_error ;
}
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-15 11:38:51 -07:00
break ;
2006-08-12 03:02:59 -07:00
case OP_PUSH :
// The type of the value is stored in with the opcode
2006-11-16 06:30:29 -08:00
sVal . type = ( INTERP_TYPE ) ( InstrPointer - > v . ival & OPCODE_DATAMASK ) ;
//ASSERT( ((INTERP_VAL *)(InstrPointer + 1))->type == sVal.type,
// "wrong value type passed for OP_PUSH: %d, expected: %d", ((INTERP_VAL *)(InstrPointer + 1))->type, sVal.type );
ASSERT ( interpCheckEquiv ( ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > type , sVal . type ) ,
" wrong value type passed for OP_PUSH: %d, expected: %d " , ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > type , sVal . type ) ;
2006-11-17 03:25:03 -08:00
/* copy value */
2006-11-16 06:30:29 -08:00
memcpy ( & sVal , ( INTERP_VAL * ) ( InstrPointer + 1 ) , sizeof ( INTERP_VAL ) ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " PUSH " ) ) ;
TRCPRINTVAL ( & sVal ) ;
TRCPRINTF ( ( " \n " ) ) ;
if ( ! stackPush ( & sVal ) )
{
// Eeerk, out of memory
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: out of memory! " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: out of memory! " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
break ;
case OP_PUSHREF :
// The type of the variable is stored in with the opcode
2006-11-16 06:30:29 -08:00
sVal . type = ( INTERP_TYPE ) ( InstrPointer - > v . ival & OPCODE_DATAMASK ) ;
2006-08-12 03:02:59 -07:00
// store the pointer
2006-11-16 06:30:29 -08:00
psVar = interpGetVarData ( psGlobals , ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > v . ival ) ;
2006-08-12 03:02:59 -07:00
sVal . v . oval = & ( psVar - > v . ival ) ;
TRCPRINTF ( ( " PUSHREF " ) ) ;
TRCPRINTVAL ( & sVal ) ;
TRCPRINTF ( ( " \n " ) ) ;
if ( ! stackPush ( & sVal ) )
{
// Eeerk, out of memory
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: out of memory! " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: out of memory! " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
break ;
case OP_POP :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_OPCODE ,
" wrong value type passed for OP_POP: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " POP \n " ) ) ;
if ( ! stackPop ( & sVal ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do stack pop " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do stack pop " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
break ;
case OP_BINARYOP :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_BINARYOP: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTMATHSOP ( data ) ;
if ( ! stackBinaryOp ( ( OPCODE ) data ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do binary op " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do binary op " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
TRCPRINTSTACKTOP ( ) ;
TRCPRINTF ( ( " \n " ) ) ;
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
break ;
case OP_UNARYOP :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_UNARYOP: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTMATHSOP ( data ) ;
if ( ! stackUnaryOp ( ( OPCODE ) data ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do unary op " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do unary op " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
TRCPRINTSTACKTOP ( ) ;
TRCPRINTF ( ( " \n " ) ) ;
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
break ;
case OP_PUSHGLOBAL :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_PUSHGLOBAL: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " PUSHGLOBAL %d \n " , data ) ) ;
if ( data > = numGlobals )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: variable index out of range " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: variable index out of range " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
if ( ! stackPush ( interpGetVarData ( psGlobals , data ) ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do stack push " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do stack push " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
break ;
case OP_POPGLOBAL :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_POPGLOBAL: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " POPGLOBAL %d " , data ) ) ;
TRCPRINTSTACKTOP ( ) ;
TRCPRINTF ( ( " \n " ) ) ;
if ( data > = numGlobals )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: variable index out of range " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: variable index out of range " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
if ( ! stackPopType ( interpGetVarData ( psGlobals , data ) ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do stack pop " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do stack pop " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
break ;
case OP_PUSHARRAYGLOBAL :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_PUSHARRAYGLOBAL: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " PUSHARRAYGLOBAL " ) ) ;
2006-09-19 09:30:50 -07:00
if ( ! interpGetArrayVarData ( & InstrPointer , psGlobals , psProg , & psVar ) )
2006-08-12 03:02:59 -07:00
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not get array var data, CurEvent=%d " , CurEvent ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not get array var data " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
TRCPRINTF ( ( " \n " ) ) ;
if ( ! stackPush ( psVar ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do stack push " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do stack push " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
break ;
case OP_POPARRAYGLOBAL :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_POPARRAYGLOBAL: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " POPARRAYGLOBAL " ) ) ;
2006-09-19 09:30:50 -07:00
if ( ! interpGetArrayVarData ( & InstrPointer , psGlobals , psProg , & psVar ) )
2006-08-12 03:02:59 -07:00
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not get array var data " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not get array var data " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
TRCPRINTSTACKTOP ( ) ;
TRCPRINTF ( ( " \n " ) ) ;
if ( ! stackPopType ( psVar ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do pop stack of type " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do pop stack of type " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
break ;
2006-11-16 06:30:29 -08:00
2006-08-12 03:02:59 -07:00
case OP_JUMPFALSE :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_JUMPFALSE: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " JUMPFALSE %d (%d) " ,
2006-09-19 09:30:50 -07:00
( SWORD ) data , InstrPointer - psProg - > pCode + ( SWORD ) data ) ) ;
2006-11-16 06:30:29 -08:00
2006-08-12 03:02:59 -07:00
if ( ! stackPop ( & sVal ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do pop of stack " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do pop of stack " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
if ( ! sVal . v . bval )
{
// Do the jump
TRCPRINTF ( ( " - done - \n " ) ) ;
2006-09-19 09:30:50 -07:00
InstrPointer + = ( SWORD ) data ;
if ( InstrPointer < pCodeStart | | InstrPointer > pCodeEnd )
2006-08-12 03:02:59 -07:00
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: jump out of range " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: jump out of range " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
}
else
{
TRCPRINTF ( ( " \n " ) ) ;
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
}
break ;
case OP_JUMP :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_JUMP: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " JUMP %d (%d) \n " ,
2006-09-19 09:30:50 -07:00
( SWORD ) data , InstrPointer - psProg - > pCode + ( SWORD ) data ) ) ;
2007-06-28 10:47:08 -07:00
// Do the jump
2006-09-19 09:30:50 -07:00
InstrPointer + = ( SWORD ) data ;
if ( InstrPointer < pCodeStart | | InstrPointer > pCodeEnd )
2007-06-28 10:47:08 -07:00
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: jump out of range " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: jump out of range " ) ;
2007-06-28 10:47:08 -07:00
goto exit_with_error ;
}
2006-08-12 03:02:59 -07:00
break ;
case OP_CALL :
2006-08-19 06:26:11 -07:00
//debug(LOG_SCRIPT, "OP_CALL");
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_OPCODE ,
" wrong value type passed for OP_CALL: %d " , InstrPointer - > type ) ;
TRCPRINTFUNC ( ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > v . pFuncExtern ) ;
2007-06-28 10:47:08 -07:00
TRCPRINTF ( ( " \n " ) ) ;
2006-11-16 06:30:29 -08:00
scriptFunc = ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > v . pFuncExtern ;
2006-08-19 06:26:11 -07:00
//debug(LOG_SCRIPT, "OP_CALL 1");
2006-08-12 03:02:59 -07:00
if ( ! scriptFunc ( ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do func " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do func " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
2006-08-19 06:26:11 -07:00
//debug(LOG_SCRIPT, "OP_CALL 2");
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-19 06:26:11 -07:00
//debug(LOG_SCRIPT, "OP_CALL 3");
2006-08-12 03:02:59 -07:00
break ;
case OP_VARCALL :
2006-11-16 06:30:29 -08:00
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_VARCALL: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " VARCALL " ) ) ;
2006-11-16 06:30:29 -08:00
TRCPRINTVARFUNC ( ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > v . pObjGetSet , data ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " (%d) \n " , data ) ) ;
2006-11-16 06:30:29 -08:00
ASSERT ( ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > type = = VAL_OBJ_GETSET ,
" wrong set/get function pointer type passed for OP_VARCALL: %d " , ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > type ) ;
scriptVarFunc = ( ( INTERP_VAL * ) ( InstrPointer + 1 ) ) - > v . pObjGetSet ;
2006-08-12 03:02:59 -07:00
if ( ! scriptVarFunc ( data ) )
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not do var func " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not do var func " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
break ;
2006-11-16 06:30:29 -08:00
case OP_EXIT : /* end of function/event, "exit" or "return" statements */
ASSERT ( InstrPointer - > type = = VAL_OPCODE ,
" wrong value type passed for OP_EXIT: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
// jump out of the code
2006-09-19 09:30:50 -07:00
InstrPointer = pCodeEnd ;
2006-08-12 03:02:59 -07:00
break ;
2006-11-16 06:30:29 -08:00
case OP_PAUSE :
ASSERT ( InstrPointer - > type = = VAL_PKOPCODE ,
" wrong value type passed for OP_PAUSE: %d " , InstrPointer - > type ) ;
2006-08-12 03:02:59 -07:00
TRCPRINTF ( ( " PAUSE %d \n " , data ) ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( stackEmpty ( ) ,
" interpRunScript: OP_PAUSE without empty stack " ) ;
2006-11-16 06:30:29 -08:00
2006-09-19 09:30:50 -07:00
InstrPointer + = aOpSize [ opcode ] ;
2006-08-12 03:02:59 -07:00
// tell the event system to reschedule this event
2006-11-16 06:30:29 -08:00
if ( ! eventAddPauseTrigger ( psContext , index , InstrPointer - pCodeBase , data ) ) //only original caller can be paused since we pass index and not CurEvent (not sure if that's what we want)
2006-08-12 03:02:59 -07:00
{
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: could not add pause trigger " ) ;
2006-08-23 05:58:48 -07:00
ASSERT ( FALSE , " interpRunScript: could not add pause trigger " ) ;
2006-08-12 03:02:59 -07:00
goto exit_with_error ;
}
// now jump out of the event
2006-09-19 09:30:50 -07:00
InstrPointer = pCodeEnd ;
2006-08-12 03:02:59 -07:00
break ;
2006-11-16 06:30:29 -08:00
case OP_TO_FLOAT :
ASSERT ( InstrPointer - > type = = VAL_OPCODE ,
" wrong value type passed for OP_TO_FLOAT: %d " , InstrPointer - > type ) ;
if ( ! castTop ( VAL_FLOAT ) )
{
debug ( LOG_ERROR , " interpRunScript: OP_TO_FLOAT failed " ) ;
goto exit_with_error ;
}
InstrPointer + = aOpSize [ opcode ] ;
break ;
case OP_TO_INT :
ASSERT ( InstrPointer - > type = = VAL_OPCODE ,
" wrong value type passed for OP_TO_INT: %d " , InstrPointer - > type ) ;
if ( ! castTop ( VAL_INT ) )
{
debug ( LOG_ERROR , " interpRunScript: OP_TO_INT failed " ) ;
goto exit_with_error ;
}
InstrPointer + = aOpSize [ opcode ] ;
break ;
2006-08-12 03:02:59 -07:00
default :
2006-11-16 06:30:29 -08:00
debug ( LOG_ERROR , " interpRunScript: unknown opcode: %d, type: %d " , opcode ) ;
ASSERT ( FALSE , " interpRunScript: unknown opcode: %d, type: %d " , opcode , InstrPointer - > type ) ;
2007-06-28 10:47:08 -07:00
goto exit_with_error ;
2006-08-12 03:02:59 -07:00
break ;
2007-06-28 10:47:08 -07:00
}
2006-08-12 03:02:59 -07:00
}
else //End of the event reached, see if we have to jump back to the caller function or just exit
{
2006-08-15 11:38:51 -07:00
//debug(LOG_SCRIPT, "End of event reached");
2006-08-12 03:02:59 -07:00
2006-09-19 09:30:50 -07:00
if ( ! retStackIsEmpty ( ) ) //There was a caller function before this one
2007-06-28 10:47:08 -07:00
{
2006-08-15 11:38:51 -07:00
//debug(LOG_SCRIPT, "GetCallDepth = %d", GetCallDepth());
2006-08-21 14:20:17 -07:00
//reset local vars (since trigger can't be called, only local vars of an event can be reset here)
if ( ! resetLocalVars ( psProg , CurEvent ) )
{
debug ( LOG_ERROR , " interpRunScript: could not reset local vars for event %d " , CurEvent ) ;
goto exit_with_error ;
}
2006-09-21 13:42:48 -07:00
//pop caller function index and return address
2006-09-19 09:30:50 -07:00
if ( ! retStackPop ( & CurEvent , & InstrPointer ) )
2006-08-12 03:02:59 -07:00
{
2006-09-21 13:42:48 -07:00
debug ( LOG_ERROR , " interpRunScript() - retStackPop() failed. " ) ;
2006-08-12 03:02:59 -07:00
return FALSE ;
}
2006-11-16 06:30:29 -08:00
//remember last called event/index
strcpy ( last_called_script_event , eventGetEventID ( psProg , CurEvent ) ) ;
2006-11-17 03:25:03 -08:00
if ( bTraceOn )
debug ( LOG_SCRIPT , " Returned to: '%s' " , last_called_script_event ) ;
2006-08-15 11:38:51 -07:00
//debug( LOG_SCRIPT, "RETURNED TO CALLER EVENT %d", CurEvent );
2006-08-12 03:02:59 -07:00
2006-11-17 03:25:03 -08:00
//Set new boundaries
2006-08-12 03:02:59 -07:00
//--------------------------
2006-09-19 09:30:50 -07:00
if ( retStackIsEmpty ( ) ) //if we jumped back to the original caller
2006-08-21 14:20:17 -07:00
{
if ( ! bEvent ) //original caller was a trigger (is it possible at all?)
{
pCodeBase = psProg - > pCode + psProg - > pTriggerTab [ CurEvent ] ;
pCodeStart = pCodeBase ;
pCodeEnd = psProg - > pCode + psProg - > pTriggerTab [ CurEvent + 1 ] ;
}
else //original caller was an event
{
pCodeBase = psProg - > pCode + psProg - > pEventTab [ CurEvent ] ;
pCodeStart = pCodeBase + offset ; //also use the offset passed, since it's an original caller event (offset is used for pause() )
pCodeEnd = psProg - > pCode + psProg - > pEventTab [ CurEvent + 1 ] ;
}
}
else //we are still jumping thru functions (this can't be a callback, since it can't/should not be called)
{
pCodeBase = psProg - > pCode + psProg - > pEventTab [ CurEvent ] ;
pCodeStart = pCodeBase ;
pCodeEnd = psProg - > pCode + psProg - > pEventTab [ CurEvent + 1 ] ;
}
2007-06-28 10:47:08 -07:00
}
2006-11-16 06:30:29 -08:00
else //we have returned to the original caller event/function
2007-06-28 10:47:08 -07:00
{
2006-08-15 11:38:51 -07:00
//debug( LOG_SCRIPT, " *** CALL STACK EMPTY ***" );
2006-08-21 14:20:17 -07:00
//reset local vars only if original caller was an event, not a trigger
if ( bEvent )
2006-08-15 11:38:51 -07:00
{
2006-08-21 14:20:17 -07:00
if ( ! resetLocalVars ( psProg , index ) )
{
debug ( LOG_ERROR , " interpRunScript: could not reset local vars " ) ;
goto exit_with_error ;
}
2006-08-15 11:38:51 -07:00
}
2006-08-12 03:02:59 -07:00
bStop = TRUE ; //Stop execution of this event here, no more calling functions stored
2007-06-28 10:47:08 -07:00
}
}
2006-08-12 03:02:59 -07:00
2007-06-28 10:47:08 -07:00
}
2006-08-12 03:02:59 -07:00
2006-08-19 06:26:11 -07:00
//debug(LOG_SCRIPT, "interpRunScript 3");
2006-08-12 03:02:59 -07:00
2006-09-19 09:30:50 -07:00
TRCPRINTF ( ( " %-6d EXIT \n " , InstrPointer - psProg - > pCode ) ) ;
2007-06-28 10:47:08 -07:00
bInterpRunning = FALSE ;
return TRUE ;
exit_with_error :
// Deal with the script crashing or running out of memory
2006-08-15 11:38:51 -07:00
debug ( LOG_ERROR , " interpRunScript: *** ERROR EXIT *** (CurEvent=%d) " , CurEvent ) ;
2006-08-19 06:26:11 -07:00
2006-08-21 14:20:17 -07:00
if ( bEvent )
debug ( LOG_ERROR , " Original event ID: %d (of %d) " , index , psProg - > numEvents ) ;
else
debug ( LOG_ERROR , " Original trigger ID: %d (of %d) " , index , psProg - > numTriggers ) ;
2006-08-19 06:26:11 -07:00
debug ( LOG_ERROR , " Current event ID: %d (of %d) " , CurEvent , psProg - > numEvents ) ;
2006-09-19 09:30:50 -07:00
callDepth = retStackCallDepth ( ) ;
2006-08-19 06:26:11 -07:00
debug ( LOG_ERROR , " Call depth : %d " , callDepth ) ;
if ( psProg - > psDebug ! = NULL )
{
debug ( LOG_ERROR , " Displaying debug info: " ) ;
if ( bEvent )
{
// find the debug info for the original (caller) event
pEventLab = eventGetEventID ( psProg , index ) ;
debug ( LOG_ERROR , " Original event name: %s " , pEventLab ) ;
pEventLab = eventGetEventID ( psProg , CurEvent ) ;
debug ( LOG_ERROR , " Current event name: %s " , pEventLab ) ;
}
else
{
// find the debug info for the trigger
pTrigLab = eventGetTriggerID ( psProg , index ) ;
debug ( LOG_ERROR , " Trigger: %s " , pTrigLab ) ;
}
}
2007-06-28 10:47:08 -07:00
TRCPRINTF ( ( " *** ERROR EXIT *** \n " ) ) ;
bInterpRunning = FALSE ;
return FALSE ;
}
/* Set the type equivalence table */
void scriptSetTypeEquiv ( TYPE_EQUIV * psTypeTab )
{
# ifdef DEBUG
SDWORD i ;
for ( i = 0 ; psTypeTab [ i ] . base ! = 0 ; i + + )
{
2006-08-23 05:58:48 -07:00
ASSERT ( psTypeTab [ i ] . base > = VAL_USERTYPESTART ,
" scriptSetTypeEquiv: can only set type equivalence for user types " ) ;
2007-06-28 10:47:08 -07:00
}
# endif
asInterpTypeEquiv = psTypeTab ;
}
/* Check if two types are equivalent */
BOOL interpCheckEquiv ( INTERP_TYPE to , INTERP_TYPE from )
{
SDWORD i , j ;
BOOL toRef = FALSE , fromRef = FALSE ;
// check for the VAL_REF flag
if ( to & VAL_REF )
{
toRef = TRUE ;
2006-11-02 11:26:55 -08:00
to = ( INTERP_TYPE ) ( to & ~ VAL_REF ) ;
2007-06-28 10:47:08 -07:00
}
if ( from & VAL_REF )
{
fromRef = TRUE ;
2006-11-02 11:26:55 -08:00
from = ( INTERP_TYPE ) ( from & ~ VAL_REF ) ;
2007-06-28 10:47:08 -07:00
}
if ( toRef ! = fromRef )
{
return FALSE ;
}
if ( to = = from )
{
return TRUE ;
}
else if ( asInterpTypeEquiv )
{
for ( i = 0 ; asInterpTypeEquiv [ i ] . base ! = 0 ; i + + )
{
if ( asInterpTypeEquiv [ i ] . base = = to )
{
for ( j = 0 ; j < asInterpTypeEquiv [ i ] . numEquiv ; j + + )
{
if ( asInterpTypeEquiv [ i ] . aEquivTypes [ j ] = = from )
{
return TRUE ;
}
}
}
}
}
return FALSE ;
}
/* Instinct function to turn on tracing */
BOOL interpTraceOn ( void )
{
interpTrace = TRUE ;
return TRUE ;
}
/* Instinct function to turn off tracing */
BOOL interpTraceOff ( void )
{
interpTrace = FALSE ;
return TRUE ;
}
2006-08-12 03:02:59 -07:00
/* Call stack stuff */
2006-09-19 09:30:50 -07:00
# define RETSTACK_SIZE 100
2006-08-12 03:02:59 -07:00
2006-09-19 09:30:50 -07:00
static ReturnAddressStack_t retStack [ RETSTACK_SIZE ] ; // Primitive stack of return addresses
static Sint8 retStackPos = - 1 ; // Current Position, always points to the last valid element
2006-08-12 03:02:59 -07:00
2006-09-20 01:16:11 -07:00
Sint8 retStackCallDepth ( void )
2006-08-12 03:02:59 -07:00
{
2006-09-19 09:30:50 -07:00
return ( retStackPos + 1 ) ;
}
2006-08-12 03:02:59 -07:00
2006-09-19 09:30:50 -07:00
static inline void retStackReset ( void )
{
retStackPos = - 1 ; // Beginning of the stack
}
2006-08-12 03:02:59 -07:00
2006-08-15 11:38:51 -07:00
2006-09-19 09:30:50 -07:00
static inline BOOL retStackIsEmpty ( void )
{
if ( retStackPos < 0 ) return TRUE ;
return FALSE ;
2006-08-12 03:02:59 -07:00
}
2006-09-19 09:30:50 -07:00
static inline BOOL retStackIsFull ( void )
2006-08-12 03:02:59 -07:00
{
2006-09-19 09:30:50 -07:00
if ( retStackPos > = RETSTACK_SIZE ) return TRUE ;
2006-08-12 03:02:59 -07:00
return FALSE ;
}
2006-09-19 09:30:50 -07:00
2006-11-16 06:30:29 -08:00
static BOOL retStackPush ( UDWORD CallerIndex , INTERP_VAL * ReturnAddress )
2006-08-12 03:02:59 -07:00
{
2006-09-19 09:30:50 -07:00
if ( retStackIsFull ( ) )
2006-08-12 03:02:59 -07:00
{
2006-09-19 09:30:50 -07:00
debug ( LOG_ERROR , " retStackPush(): return address stack is full " ) ;
return FALSE ; // Stack full
2006-08-12 03:02:59 -07:00
}
2006-09-19 09:30:50 -07:00
retStackPos + + ;
retStack [ retStackPos ] . CallerIndex = CallerIndex ;
retStack [ retStackPos ] . ReturnAddress = ReturnAddress ;
2006-08-12 03:02:59 -07:00
2006-09-21 13:42:48 -07:00
//debug( LOG_SCRIPT, "retStackPush: Event=%i Address=%p, ", CallerIndex, ReturnAddress);
2006-08-12 03:02:59 -07:00
return TRUE ;
}
2006-09-19 09:30:50 -07:00
2006-11-16 06:30:29 -08:00
static BOOL retStackPop ( UDWORD * CallerIndex , INTERP_VAL * * ReturnAddress )
2006-08-12 03:02:59 -07:00
{
2006-09-19 09:30:50 -07:00
if ( retStackIsEmpty ( ) )
{
debug ( LOG_ERROR , " retStackPop(): return address stack is empty " ) ;
return FALSE ;
}
* CallerIndex = retStack [ retStackPos ] . CallerIndex ;
* ReturnAddress = retStack [ retStackPos ] . ReturnAddress ;
retStackPos - - ;
//debug( LOG_SCRIPT, "retStackPop: Event=%i Address=%p", *EventTrigIndex, *ReturnAddress);
return TRUE ;
2006-08-12 09:52:37 -07:00
}