예제 #1
0
파일: hp.cpp 프로젝트: kavon/SALSA
// Goes over the list of nodes that needs to be freed
// and frees them if no HP points at them.
void scan(HPLocal localData) {
	int i;
	//Stage 1: scan HP list and insert non-null values to plist
	Set plist = localData->plist;
	setReset(plist);
	HPRecord* curr = localData->HPRecHead;
	while (curr != NULL) {
		for (i = 0; i < localData->hpData->HP_COUNT; i++) {
			if (curr->hp[i] != NULL) {
				setAdd(plist, (long) (curr->hp[i]));
			}
		}
		curr = curr->next;
	}
	//Stage 2: search plist
	//uses two stacks instead of allocating a new one each time scan() is called
	SwapStacks(&localData->rlist, &localData->temp);
	stackReset(localData->rlist);
	ReclaimationData* recData = stackPop(localData->temp);
	while (recData != NULL) {
		if (setContains(plist, (long) recData->address)) {
			stackPush(localData->rlist, recData->address,
					recData->reclaimationFunc);
		} else {
				(*((ReclaimationFunc*)recData->reclaimationFunc))(recData->address);
		}
		recData = stackPop(localData->temp);
	}
	setReset(plist);
}
예제 #2
0
void stackInit( Stack *theStack, NewStack *theNewStack, long Index )
{
    stackReset( theStack );
    theStack->st_Left = theNewStack->ns_Left;
    theStack->st_Top = theNewStack->ns_Top;
    theStack->st_Index = ( uchar )Index;
    theStack->st_ClassIdx = theNewStack->ns_ClassIdx;
    theStack->st_Owner = theNewStack->ns_Owner;
    theStack->st_Suit = theNewStack->ns_Suit;
}
예제 #3
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
			}
		}

	}