예제 #1
0
// Run a trigger
static BOOL eventFireTrigger(ACTIVE_TRIGGER *psTrigger)
{
	BOOL			fired;
	INTERP_VAL		sResult;

	fired = false;
	psFiringTrigger = psTrigger;

	// If this is a code trigger see if it fires
	if (psTrigger->type == TR_CODE)
	{
		// Run the trigger
		if (!interpRunScript(psTrigger->psContext,
						IRT_TRIGGER, psTrigger->trigger, 0))
		{
			ASSERT( false, "eventFireTrigger: trigger %s: code failed",
					eventGetTriggerID(psTrigger->psContext->psCode, psTrigger->trigger) );
			return false;
		}
		// Get the result
		sResult.type = VAL_BOOL;
		if (!stackPopType(&sResult))
		{
			return false;
		}
		fired = sResult.v.bval;
	}
	else
	{
		fired = true;
	}

	// If it fired run the event
	if (fired)
	{
		DB_TRIGINF(psTrigger,1);
		DB_TRACE(" fired", 1);
		if (!interpRunScript(psTrigger->psContext, IRT_EVENT, psTrigger->event, psTrigger->offset))
		{
			DB_TRACE(("********  script failed  *********"), 0);
			DB_TRIGINF(psTrigger,0);
			ASSERT(false, "eventFireTrigger: event %s: code failed",
			       eventGetEventID(psTrigger->psContext->psCode, psTrigger->event));
			return false;
		}
	}
#ifdef DEBUG
	else
	{
		DB_TRIGINF(psTrigger,3);
	}
#endif

	return true;
}
예제 #2
0
// Print out all the info available about a trigger
static void eventPrintTriggerInfo(ACTIVE_TRIGGER *psTrigger)
{
	SCRIPT_CODE *psCode = psTrigger->psContext->psCode;
	const char	*pTrigLab, *pEventLab;

	// find the debug info for the trigger
	pTrigLab = eventGetTriggerID(psCode, psTrigger->trigger);
	// find the debug info for the event
	pEventLab = eventGetEventID(psCode, psTrigger->event);

	debug(LOG_WARNING, "trigger %s at %d -> %s", pTrigLab, psTrigger->testTime, pEventLab);
	if (psTrigger->offset != 0)
	{
		debug(LOG_WARNING, " %d", psTrigger->offset);
	}
}
예제 #3
0
// Change the trigger assigned to an event - to be called from script functions
BOOL eventSetTrigger(void)
{
	ACTIVE_TRIGGER	*psTrigger;
	UDWORD			event;
	SDWORD			trigger;
	SCRIPT_CONTEXT	*psContext;

	if (!stackPopParams(2, VAL_EVENT, &event, VAL_TRIGGER, &trigger))
	{
		return false;
	}

#ifdef REALLY_DEBUG_THIS
	DB_TRACE(("eventSetTrigger %s %s\n",
		eventGetEventID(psFiringTrigger->psContext->psCode, event),
		eventGetTriggerID(psFiringTrigger->psContext->psCode, trigger)),2);
#endif

	// See if this is the event that is running
	psContext = psFiringTrigger->psContext;
	if (psFiringTrigger->event == event)
	{
		psFiringTrigger->deactivated = true;
	}
	else
	{
		// Mark the old trigger in the lists
		eventMarkTriggerInList(&psTrigList, psContext, event, &trigger);
		eventMarkTriggerInList(&psCallbackList, psContext, event, &trigger);
		eventMarkTriggerInList(&psAddedTriggers, psContext, event, &trigger);
	}

	// Create a new trigger if necessary
	if (trigger >= 0)
	{
		if (!eventInitTrigger(&psTrigger, psFiringTrigger->psContext,
							event, trigger, updateTime))
		{
			return false;
		}
		psTrigger->psNext = psAddedTriggers;
		psAddedTriggers = psTrigger;
	}

	return true;
}
예제 #4
0
// Activate a callback trigger
void eventFireCallbackTrigger(TRIGGER_TYPE callback)
{
	ACTIVE_TRIGGER	*psPrev = NULL, *psCurr, *psNext;
	TRIGGER_DATA	*psTrigDat;
	BOOL		fired;

	if (interpProcessorActive())
	{
		ASSERT(false, "eventFireCallbackTrigger: script interpreter is already running");
		return;
	}

	//this can be called from eventProcessTriggers and so will wipe out all the current added ones
	//psAddedTriggers = NULL;
	for (psCurr = psCallbackList; psCurr && psCurr->type <= (int)callback; psCurr = psNext)
	{
		psNext = psCurr->psNext;
		if (psCurr->type == (int)callback)
		{
			// see if the callback should be fired
			fired = false;
			if (psCurr->type != TR_PAUSE)
			{
				ASSERT(psCurr->trigger >= 0 && psCurr->trigger < psCurr->psContext->psCode->numTriggers,
				       "eventFireCallbackTrigger: invalid trigger number");
				psTrigDat = psCurr->psContext->psCode->psTriggerData + psCurr->trigger;
			}
			else
			{
				psTrigDat = NULL;
			}
			if (psTrigDat && psTrigDat->code)
			{
				if (!interpRunScript(psCurr->psContext, IRT_TRIGGER, psCurr->trigger, 0))
				{
					ASSERT(false, "eventFireCallbackTrigger: trigger %s: code failed",
					       eventGetTriggerID(psCurr->psContext->psCode, psCurr->trigger));
					psPrev = psCurr;
					continue;
				}
				if (!stackPopParams(1, VAL_BOOL, &fired))
				{
					ASSERT(false, "eventFireCallbackTrigger: trigger %s: code failed",
					       eventGetTriggerID(psCurr->psContext->psCode, psCurr->trigger));
					psPrev = psCurr;
					continue;
				}
			}
			else
			{
				fired = true;
			}

			// run the event
			if (fired)
			{
				DB_TRIGINF(psCurr,1);
				DB_TRACE(" fired",1);

				// remove the trigger from the list
				if (psPrev == NULL)
				{
					psCallbackList = psCallbackList->psNext;
				}
				else
				{
					psPrev->psNext = psNext;
				}

				psFiringTrigger = psCurr;
				if (!interpRunScript(psCurr->psContext, IRT_EVENT, psCurr->event, psCurr->offset)) // this could set psCurr->deactivated
				{
					ASSERT(false, "eventFireCallbackTrigger: event %s: code failed",
					       eventGetEventID(psCurr->psContext->psCode, psCurr->event));
				}
				if (psCurr->deactivated)
				{
					// don't need to add the trigger again - just free it
					eventFreeTrigger(psCurr);
				}
				else
				{
					// make sure the trigger goes back into the system
					psCurr->psNext = psAddedTriggers;
					psAddedTriggers = psCurr;
				}
			}
			else
			{
				psPrev = psCurr;
			}
		}
		else
		{
			psPrev = psCurr;
		}
	}

	// Delete marked triggers now
	eventPruneLists();

	// Now add all the new triggers
	for(psCurr = psAddedTriggers; psCurr; psCurr=psNext)
	{
		psNext = psCurr->psNext;
		eventAddTrigger(psCurr);
	}
	//clear out after added them all
	psAddedTriggers = NULL;
}
예제 #5
0
/* Run a compiled script */
bool interpRunScript(SCRIPT_CONTEXT *psContext, INTERP_RUNTYPE runType, UDWORD index, UDWORD offset)
{
	UDWORD			data;
	OPCODE			opcode;
	INTERP_VAL		sVal, *psVar,*InstrPointer;
	VAL_CHUNK		*psGlobals;
	UDWORD			numGlobals = 0;
	INTERP_VAL		*pCodeStart, *pCodeEnd, *pCodeBase;
	SCRIPT_FUNC		scriptFunc = 0;
	SCRIPT_VARFUNC	scriptVarFunc = 0;
	SCRIPT_CODE		*psProg;
	SDWORD			instructionCount = 0;

	UDWORD			CurEvent = 0;
	bool			bStop = false, bEvent = false;
	UDWORD			callDepth = 0;
	bool			bTraceOn=false;		//enable to debug function/event calls

	ASSERT(psContext != NULL, "Invalid context pointer");

	psProg = psContext->psCode;
	psCurProg = psProg;		//remember for future use

	ASSERT(psProg != NULL, "Invalid script code pointer");

	if (bInterpRunning)
	{
		debug(LOG_ERROR, "Interpreter already running"
			"                 - callback being called from within a script function?");
		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();

	//reset return stack
	retStackReset();

	// Turn off tracing initially
	interpTrace = false;

	/* Get the global variables */
	numGlobals = psProg->numGlobals;
	psGlobals = psContext->psGlobals;

	bEvent = false;

	// Find the code range
	switch (runType)
	{
	case IRT_TRIGGER:
		if (index > psProg->numTriggers)
		{
			ASSERT(false, "Trigger index out of range");
			return false;
		}
		pCodeBase = psProg->pCode + psProg->pTriggerTab[index];
		pCodeStart = pCodeBase;
		pCodeEnd  = psProg->pCode + psProg->pTriggerTab[index+1];

		bCurCallerIsEvent = false;

		// find the debug info for the trigger
		strcpy(last_called_script_event, eventGetTriggerID(psProg, index));

		if(bTraceOn)
			debug(LOG_SCRIPT,"Trigger: %s", last_called_script_event);

		break;
	case IRT_EVENT:
		if (index > psProg->numEvents)
		{
			ASSERT(false, "Trigger index out of range");
			return false;
		}
		pCodeBase = psProg->pCode + psProg->pEventTab[index];
		pCodeStart = pCodeBase + offset;		//offset only used for pause() script function
		pCodeEnd  = psProg->pCode + psProg->pEventTab[index+1];

		bEvent = true; //remember it's an event
		bCurCallerIsEvent = true;

		// remember last called event/function
		strcpy(last_called_script_event, eventGetEventID(psProg, index));

		if(bTraceOn)
			debug(LOG_SCRIPT,"Original event name: %s", last_called_script_event);

		break;
	default:
		ASSERT(false, "Unknown run type");
		return false;
	}

	// Get the first opcode
	InstrPointer = pCodeStart;

	/* 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;

	instructionCount = 0;

	CurEvent = index;
	bStop = false;

	// create new variable environment for this call
	if (bEvent)
	{
		createVarEnvironment(psContext, CurEvent);
	}

	while(!bStop)
	{
		// Run the code
		if (InstrPointer < pCodeEnd)// && opcode != OP_EXIT)
		{
			if (instructionCount > INTERP_MAXINSTRUCTIONS)
			{
				debug( LOG_ERROR, "interpRunScript: max instruction count exceeded - infinite loop ?" );
				goto exit_with_error;
			}
			instructionCount++;

			TRCPRINTF( "%-6d  ", (int)(InstrPointer - psProg->pCode) );
			opcode = (OPCODE)(InstrPointer->v.ival >> OPCODE_SHIFT);			//get opcode
			data = (SDWORD)(InstrPointer->v.ival & OPCODE_DATAMASK);		//get data - only used with packed opcodes
			switch (opcode)
			{
				/* Custom function call */
				case OP_FUNC:
					//debug( LOG_SCRIPT, "-OP_FUNC" );
					//debug( LOG_SCRIPT, "OP_FUNC: remember event %d, ip=%d", CurEvent, (ip + 2) );

					if(!retStackPush(CurEvent, (InstrPointer + aOpSize[opcode]))) //Remember where to jump back later
					{
						debug( LOG_ERROR, "interpRunScript() - retStackPush() failed.");
						return false;
					}

					ASSERT(((INTERP_VAL *)(InstrPointer+1))->type == VAL_EVENT, "wrong value type passed for OP_FUNC: %d", ((INTERP_VAL *)(InstrPointer+1))->type);

					// get index of the new event
					CurEvent = ((INTERP_VAL *)(InstrPointer+1))->v.ival; //Current event = event to jump to

					if (CurEvent > psProg->numEvents)
					{
						debug( LOG_ERROR, "interpRunScript: trigger index out of range");
						goto exit_with_error;
					}

					// create new variable environment for this call
					createVarEnvironment(psContext, CurEvent);

					//Set new code execution boundaries
					//----------------------------------
					pCodeBase = psProg->pCode + psProg->pEventTab[CurEvent];
					pCodeStart = pCodeBase;
					pCodeEnd  = psProg->pCode + psProg->pEventTab[CurEvent+1];

					InstrPointer = pCodeStart;				//Start at the beginning of the new event

					//remember last called event/index
					strcpy(last_called_script_event, eventGetEventID(psProg, CurEvent));

					if(bTraceOn)
						debug(LOG_SCRIPT,"Called: '%s'", last_called_script_event);

					//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" );

					break;

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

				if (data >= psContext->psCode->numLocalVars[CurEvent])
				{
					debug(LOG_ERROR, "interpRunScript: OP_PUSHLOCAL: variable index out of range");
					goto exit_with_error;
				}

				//debug(LOG_SCRIPT, "OP_PUSHLOCAL type: %d", psContext->psCode->ppsLocalVarVal[CurEvent][data].type);

				if (!stackPush( &(varEnvironment[retStackCallDepth()][data]) ))
				{
					debug(LOG_ERROR, "interpRunScript: OP_PUSHLOCAL: push failed");
					goto exit_with_error;
				}

				InstrPointer += aOpSize[opcode];
				break;
			case OP_POPLOCAL:

				//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");
					goto exit_with_error;
				}

				//DbgMsg("OP_POPLOCAL type: %d, CurEvent=%d, data=%d", psContext->psCode->ppsLocalVarVal[CurEvent][data].type, CurEvent, data);

				if ( !stackPopType( &(varEnvironment[retStackCallDepth()][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);

				InstrPointer += aOpSize[opcode];

				break;

			case OP_PUSHLOCALREF:

				// The type of the variable is stored in with the opcode
				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);

				/* get local var index */
				data = ((INTERP_VAL *)(InstrPointer + 1))->v.ival;

				if (data >= psContext->psCode->numLocalVars[CurEvent])
				{
					debug(LOG_ERROR, "interpRunScript: OP_PUSHLOCALREF: variable index out of range");
					goto exit_with_error;
				}

				/* get local variable */
				sVal.v.oval = &(varEnvironment[retStackCallDepth()][data]);

				TRCPRINTOPCODE(opcode);
				TRCPRINTVAL(sVal);
				TRCPRINTF( "\n" );

				if (!stackPush(&sVal))
				{
					debug(LOG_ERROR, "interpRunScript: OP_PUSHLOCALREF: push failed");
					goto exit_with_error;
				}
				InstrPointer += aOpSize[opcode];
				break;

			case OP_PUSH:
				// The type of the value is stored in with the opcode
				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);

				/* copy value */
				memcpy(&sVal, (INTERP_VAL *)(InstrPointer + 1), sizeof(INTERP_VAL));

				TRCPRINTOPCODE(opcode);
				TRCPRINTVAL(sVal);
				TRCPRINTF( "\n" );
				if (!stackPush(&sVal))
				{
					// Eeerk, out of memory
					debug( LOG_ERROR, "interpRunScript: out of memory!" );
					goto exit_with_error;
				}
				InstrPointer += aOpSize[opcode];
				break;
			case OP_PUSHREF:
				// The type of the variable is stored in with the opcode
				sVal.type = (INTERP_TYPE)(InstrPointer->v.ival & OPCODE_DATAMASK);

				// store pointer to INTERP_VAL
				sVal.v.oval = interpGetVarData(psGlobals, ((INTERP_VAL *)(InstrPointer + 1))->v.ival);

				TRCPRINTOPCODE(opcode);
				TRCPRINTVAL(sVal);
				TRCPRINTF( "\n" );
				if (!stackPush(&sVal))
				{
					// Eeerk, out of memory
					debug( LOG_ERROR, "interpRunScript: out of memory!" );
					goto exit_with_error;
				}
				InstrPointer += aOpSize[opcode];
				break;
			case OP_POP:
				ASSERT( InstrPointer->type == VAL_OPCODE,
					"wrong value type passed for OP_POP: %d", InstrPointer->type);

				TRCPRINTOPCODE(opcode);
				if (!stackPop(&sVal))
				{
					debug( LOG_ERROR, "interpRunScript: could not do stack pop" );
					goto exit_with_error;
				}
				InstrPointer += aOpSize[opcode];
				break;
			case OP_BINARYOP:
				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_BINARYOP: %d", InstrPointer->type);

				TRCPRINTOPCODE(data);
				if (!stackBinaryOp((OPCODE)data))
				{
					debug( LOG_ERROR, "interpRunScript: could not do binary op" );
					goto exit_with_error;
				}
				TRCPRINTSTACKTOP();
				TRCPRINTF( "\n" );
				InstrPointer += aOpSize[opcode];
				break;
			case OP_UNARYOP:
				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_UNARYOP: %d", InstrPointer->type);

				TRCPRINTOPCODE(data);
				if (!stackUnaryOp((OPCODE)data))
				{
					debug( LOG_ERROR, "interpRunScript: could not do unary op" );
					goto exit_with_error;
				}
				TRCPRINTSTACKTOP();
				TRCPRINTF( "\n" );
				InstrPointer += aOpSize[opcode];
				break;
			case OP_PUSHGLOBAL:

				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_PUSHGLOBAL: %d", InstrPointer->type);

				TRCPRINTF( "PUSHGLOBAL  %d\n", data );
				if (data >= numGlobals)
				{
					debug( LOG_ERROR, "interpRunScript: variable index out of range" );
					goto exit_with_error;
				}
				if (!stackPush(interpGetVarData(psGlobals, data)))
				{
					debug( LOG_ERROR, "interpRunScript: could not do stack push" );
					goto exit_with_error;
				}
				InstrPointer += aOpSize[opcode];
				break;
			case OP_POPGLOBAL:
				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_POPGLOBAL: %d", InstrPointer->type);

				TRCPRINTF( "POPGLOBAL   %d ", data );
				TRCPRINTSTACKTOP();
				TRCPRINTF( "\n" );
				if (data >= numGlobals)
				{
					debug( LOG_ERROR, "interpRunScript: variable index out of range" );
					goto exit_with_error;
				}
				if (!stackPopType(interpGetVarData(psGlobals, data)))
				{
					debug( LOG_ERROR, "interpRunScript: could not do stack pop" );
					goto exit_with_error;
				}
				InstrPointer += aOpSize[opcode];
				break;
			case OP_PUSHARRAYGLOBAL:
				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_PUSHARRAYGLOBAL: %d", InstrPointer->type);

				TRCPRINTOPCODE(opcode);
				if (!interpGetArrayVarData(&InstrPointer, psGlobals, psProg, &psVar))
				{
					debug( LOG_ERROR, "interpRunScript: could not get array var data, CurEvent=%d", CurEvent );
					goto exit_with_error;
				}
				TRCPRINTF( "\n" );
				if (!stackPush(psVar))
				{
					debug( LOG_ERROR, "interpRunScript: could not do stack push" );
					goto exit_with_error;
				}
				break;
			case OP_POPARRAYGLOBAL:
				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_POPARRAYGLOBAL: %d", InstrPointer->type);

				TRCPRINTOPCODE(opcode);
				if (!interpGetArrayVarData(&InstrPointer, psGlobals, psProg, &psVar))
				{
					debug( LOG_ERROR, "interpRunScript: could not get array var data" );
					goto exit_with_error;
				}
				TRCPRINTSTACKTOP();
				TRCPRINTF( "\n" );
				if (!stackPopType(psVar))
				{
					debug( LOG_ERROR, "interpRunScript: could not do pop stack of type" );
					goto exit_with_error;
				}
				break;

			case OP_JUMPFALSE:
				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_JUMPFALSE: %d", InstrPointer->type);

				TRCPRINTF( "JUMPFALSE   %d (%d)",
				           (SWORD)data, (int)(InstrPointer - psProg->pCode + (SWORD)data) );

				if (!stackPop(&sVal))
				{
					debug( LOG_ERROR, "interpRunScript: could not do pop of stack" );
					goto exit_with_error;
				}
				if (!sVal.v.bval)
				{
					// Do the jump
					TRCPRINTF( " - done -\n" );
					InstrPointer += (SWORD)data;
					if (InstrPointer < pCodeStart || InstrPointer > pCodeEnd)
					{
						debug( LOG_ERROR, "interpRunScript: jump out of range" );
						goto exit_with_error;
					}
				}
				else
				{
					TRCPRINTF( "\n" );
					InstrPointer += aOpSize[opcode];
				}
				break;
			case OP_JUMP:
				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_JUMP: %d", InstrPointer->type);

				TRCPRINTF( "JUMP        %d (%d)\n",
				           (SWORD)data, (int)(InstrPointer - psProg->pCode + (SWORD)data) );
				// Do the jump
				InstrPointer += (SWORD)data;
				if (InstrPointer < pCodeStart || InstrPointer > pCodeEnd)
				{
					debug( LOG_ERROR, "interpRunScript: jump out of range" );
					goto exit_with_error;
				}
				break;
			case OP_CALL:
				//debug(LOG_SCRIPT, "OP_CALL");

				ASSERT( InstrPointer->type == VAL_OPCODE,
					"wrong value type passed for OP_CALL: %d", InstrPointer->type);

				scriptFunc = ((INTERP_VAL *)(InstrPointer+1))->v.pFuncExtern;
				TRCPRINTFUNC( scriptFunc );
				TRCPRINTF( "\n" );
				//debug(LOG_SCRIPT, "OP_CALL 1");
				if (!scriptFunc())
				{
					debug( LOG_ERROR, "interpRunScript: could not do func" );
					goto exit_with_error;
				}
				//debug(LOG_SCRIPT, "OP_CALL 2");
				InstrPointer += aOpSize[opcode];
				//debug(LOG_SCRIPT, "OP_CALL 3");
				break;
			case OP_VARCALL:
				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_VARCALL: %d", InstrPointer->type);

				TRCPRINTOPCODE(opcode);
				TRCPRINTVARFUNC(  ((INTERP_VAL *)(InstrPointer+1))->v.pObjGetSet, data );
				TRCPRINTF( "(%d)\n", data );

				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;
				if (!scriptVarFunc(data))
				{
					debug( LOG_ERROR, "interpRunScript: could not do var func" );
					goto exit_with_error;
				}
				InstrPointer += aOpSize[opcode];
				break;
			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);

				// jump out of the code
				InstrPointer = pCodeEnd;
				break;
			case OP_PAUSE:
				ASSERT( InstrPointer->type == VAL_PKOPCODE,
					"wrong value type passed for OP_PAUSE: %d", InstrPointer->type);

				TRCPRINTF( "PAUSE       %d\n", data );
				ASSERT( stackEmpty(),
					"interpRunScript: OP_PAUSE without empty stack" );

				InstrPointer += aOpSize[opcode];
				// tell the event system to reschedule this event
				if (!eventAddPauseTrigger(psContext, index, (UDWORD)(InstrPointer - pCodeBase), data))	//only original caller can be paused since we pass index and not CurEvent (not sure if that's what we want)
				{
					debug( LOG_ERROR, "interpRunScript: could not add pause trigger" );
					goto exit_with_error;
				}
				// now jump out of the event
				InstrPointer = pCodeEnd;
				break;
			case OP_TO_FLOAT:
				ASSERT( InstrPointer->type == VAL_OPCODE,
					"wrong value type passed for OP_TO_FLOAT: %d", InstrPointer->type);

				if(!stackCastTop(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(!stackCastTop(VAL_INT))
				{
					debug( LOG_ERROR, "interpRunScript: OP_TO_INT failed" );
					goto exit_with_error;
				}
				InstrPointer += aOpSize[opcode];
				break;
			default:
				debug(LOG_ERROR, "interpRunScript: unknown opcode: %d, type: %d", opcode, InstrPointer->type);
				goto exit_with_error;
				break;
			}
		}
		else	//End of the event reached, see if we have to jump back to the caller function or just exit
		{
			//debug(LOG_SCRIPT, "End of event reached");

			if(!retStackIsEmpty())		//There was a caller function before this one
			{
				// destroy current variable environment
				destroyVarEnvironment(psContext, retStackCallDepth(), CurEvent);

				//pop caller function index and return address
				if (!retStackPop(&CurEvent, &InstrPointer))
				{
					debug( LOG_ERROR, "interpRunScript() - retStackPop() failed.");
					return false;
				}

				//remember last called event/index
				strcpy(last_called_script_event, eventGetEventID(psProg, CurEvent));

				if(bTraceOn)
					debug(LOG_SCRIPT,"Returned to: '%s'", last_called_script_event);

				//debug( LOG_SCRIPT, "RETURNED TO CALLER EVENT %d", CurEvent );

				//Set new boundaries
				//--------------------------
				if(retStackIsEmpty())	//if we jumped back to the original caller
				{
					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];
				}
			}
			else		//we have returned to the original caller event/function
			{
				//debug( LOG_SCRIPT, " *** CALL STACK EMPTY ***" );

				//reset local vars only if original caller was an event, not a trigger
				if(bEvent)
				{
					// destroy current variable environment
					destroyVarEnvironment(psContext, retStackCallDepth(), CurEvent);
				}

				bStop = true;		//Stop execution of this event here, no more calling functions stored
			}
		}

	}