Revert 4344-4347, 4355, 4357, 4358, 4362: They caused too much slowdown in the scripting engine
git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@4379 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
88fc127503
commit
f888cc5b69
|
@ -348,9 +348,10 @@ BOOL eventNewContext(SCRIPT_CODE *psCode, CONTEXT_RELEASE release,
|
|||
SCRIPT_CONTEXT **ppsContext)
|
||||
{
|
||||
SCRIPT_CONTEXT *psContext;
|
||||
SDWORD val, storeIndex, arrayNum, arraySize = 1;
|
||||
SDWORD val, storeIndex, arrayNum, arraySize;
|
||||
UDWORD i, j;
|
||||
INTERP_TYPE type;
|
||||
VAL_CHUNK *psNewChunk, *psNextChunk;
|
||||
unsigned int i;
|
||||
|
||||
ASSERT(psCode != NULL, "eventNewContext: Invalid code pointer");
|
||||
|
||||
|
@ -368,13 +369,12 @@ BOOL eventNewContext(SCRIPT_CODE *psCode, CONTEXT_RELEASE release,
|
|||
psContext->release = release;
|
||||
psContext->psGlobals = NULL;
|
||||
psContext->id = -1; // only used by the save game
|
||||
|
||||
val = psCode->numGlobals + psCode->arraySize - 1;
|
||||
arrayNum = psCode->numArrays - 1;
|
||||
|
||||
arraySize = 1;
|
||||
if (psCode->numArrays > 0)
|
||||
{
|
||||
for(i = 0; i<psCode->psArrayInfo[arrayNum].dimensions; i++)
|
||||
for(i=0; i<psCode->psArrayInfo[arrayNum].dimensions; i++)
|
||||
{
|
||||
arraySize *= psCode->psArrayInfo[arrayNum].elements[i];
|
||||
}
|
||||
|
@ -383,39 +383,55 @@ BOOL eventNewContext(SCRIPT_CODE *psCode, CONTEXT_RELEASE release,
|
|||
|
||||
//prepare local variables (initialize, store type)
|
||||
//-------------------------------
|
||||
for(i = 0; i < psCode->numEvents; i++)
|
||||
psCode->ppsLocalVarVal = (INTERP_VAL **)malloc(sizeof(INTERP_VAL*) * psCode->numEvents); //allocate space for array of local var arrays for each event
|
||||
|
||||
debug(LOG_SCRIPT,"allocated space for %d events", psCode->numEvents);
|
||||
|
||||
for(i=0;i < psCode->numEvents; i++)
|
||||
{
|
||||
if(psCode->numLocalVars[i] > 0) //this event has any local vars declared
|
||||
{
|
||||
unsigned int j;
|
||||
psCode->ppsLocalVarVal[i] = (INTERP_VAL*)malloc(sizeof(INTERP_VAL) * psCode->numLocalVars[i]); //allocate space for local vars array (for the current event)
|
||||
|
||||
debug(LOG_SCRIPT,"Event %d has %d local variables", i, psCode->numLocalVars[i]);
|
||||
|
||||
for(j = 0; j < psCode->numLocalVars[i]; j++)
|
||||
for(j=0; j < psCode->numLocalVars[i]; j++)
|
||||
{
|
||||
INTERP_TYPE type = psCode->ppsLocalVars[i][j].type;
|
||||
type = psCode->ppsLocalVars[i][j];
|
||||
|
||||
if (!interpInitValue(type, &psCode->ppsLocalVars[i][j]))
|
||||
{
|
||||
debug(LOG_ERROR, "eventNewContext: failed to init local value");
|
||||
return false;
|
||||
//debug(LOG_SCRIPT,"var %d's type: %d", i, type);
|
||||
|
||||
/* initialize Strings, integers, floats etc
|
||||
memset to 0, the only special case is strings */
|
||||
memset (&(psCode->ppsLocalVarVal[i][j]), 0, sizeof(INTERP_VAL));
|
||||
if (type == VAL_STRING) {
|
||||
psCode->ppsLocalVarVal[i][j].v.sval = (char*)malloc(MAXSTRLEN);
|
||||
strcpy(psCode->ppsLocalVarVal[i][j].v.sval,"\0");
|
||||
}
|
||||
|
||||
//Initialize objects
|
||||
if (asCreateFuncs != NULL && type < numFuncs && asCreateFuncs[type])
|
||||
{
|
||||
if (!asCreateFuncs[type](&(psCode->ppsLocalVars[i][j])))
|
||||
if (!asCreateFuncs[type](&(psCode->ppsLocalVarVal[i][j]) ))
|
||||
{
|
||||
debug(LOG_ERROR,"eventNewContext: asCreateFuncs failed for local var");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
psCode->ppsLocalVarVal[i][j].type = type; //store (copy) var type (data used during parsing -> data used during interpreting)
|
||||
|
||||
//debug(LOG_SCRIPT, "i=%d, j=%d, value=%d",i,j,psCode->ppsLocalVarVal[i][j].v.ival);
|
||||
}
|
||||
|
||||
//debug(LOG_SCRIPT,"------");
|
||||
|
||||
}
|
||||
else //this event has no local vars
|
||||
{
|
||||
psCode->ppsLocalVars[i] = NULL;
|
||||
psCode->ppsLocalVarVal[i] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (val >= 0)
|
||||
|
@ -436,8 +452,6 @@ BOOL eventNewContext(SCRIPT_CODE *psCode, CONTEXT_RELEASE release,
|
|||
storeIndex = val % CONTEXT_VALS;
|
||||
while (storeIndex >= 0)
|
||||
{
|
||||
INTERP_TYPE type;
|
||||
|
||||
if (val >= psCode->numGlobals)
|
||||
{
|
||||
type = psCode->psArrayInfo[arrayNum].type;
|
||||
|
@ -448,12 +462,16 @@ BOOL eventNewContext(SCRIPT_CODE *psCode, CONTEXT_RELEASE release,
|
|||
}
|
||||
|
||||
// initialize Strings, integers etc
|
||||
if (!interpInitValue(type, &psNewChunk->asVals[storeIndex]))
|
||||
{
|
||||
debug(LOG_ERROR, "eventNewContext: failed to init global value");
|
||||
return false;
|
||||
// memset to 0
|
||||
memset(&(psNewChunk->asVals[storeIndex]), 0, sizeof(INTERP_VAL));
|
||||
if (type == VAL_STRING) {
|
||||
psNewChunk->asVals[storeIndex].v.sval = (char*)malloc(MAXSTRLEN);
|
||||
strcpy(psNewChunk->asVals[storeIndex].v.sval,"\0");
|
||||
}
|
||||
|
||||
// set type
|
||||
psNewChunk->asVals[storeIndex].type = type;
|
||||
|
||||
//initialize objects
|
||||
if (asCreateFuncs != NULL && type < numFuncs && asCreateFuncs[type])
|
||||
{
|
||||
|
|
|
@ -968,83 +968,6 @@ void scriptSetTypeEquiv(TYPE_EQUIV *psTypeTab)
|
|||
}
|
||||
|
||||
|
||||
BOOL interpInitValue(INTERP_TYPE type, INTERP_VAL *value)
|
||||
{
|
||||
memset(value, 0, sizeof(*value));
|
||||
|
||||
value->type = type;
|
||||
switch (type)
|
||||
{
|
||||
case VAL_STRING:
|
||||
value->v.sval = malloc(MAXSTRLEN);
|
||||
if (value->v.sval == NULL)
|
||||
{
|
||||
debug(LOG_ERROR, "interpInitValue(string): Out of memory");
|
||||
return false;
|
||||
}
|
||||
value->v.sval[0] = '\0';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void interpCleanValue(INTERP_VAL *value)
|
||||
{
|
||||
switch (value->type)
|
||||
{
|
||||
case VAL_STRING:
|
||||
free(value->v.sval);
|
||||
value->v.sval = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL interpCopyValue(INTERP_VAL *to, INTERP_VAL *from, BOOL deep)
|
||||
{
|
||||
/* Check whether we can do a direct copy */
|
||||
if (interpCheckEquiv(to->type, from->type))
|
||||
{
|
||||
if (deep && to->type == VAL_STRING)
|
||||
{
|
||||
return (strlcpy(to->v.sval, from->v.sval, MAXSTRLEN) != 0);
|
||||
}
|
||||
return (memcpy(&(to->v), &(from->v), sizeof(to->v)) != NULL);
|
||||
}
|
||||
|
||||
/* Or have to do an implicit conversion */
|
||||
switch (to->type)
|
||||
{
|
||||
case VAL_STRING:
|
||||
switch (from->type)
|
||||
{
|
||||
case VAL_BOOL:
|
||||
return (snprintf(to->v.sval, MAXSTRLEN, "%d", from->v.bval) != 0);
|
||||
case VAL_INT:
|
||||
return (snprintf(to->v.sval, MAXSTRLEN, "%d", from->v.ival) != 0);
|
||||
case VAL_FLOAT:
|
||||
return (snprintf(to->v.sval, MAXSTRLEN, "%f", from->v.fval) != 0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT( false,
|
||||
"interpCopyValue: type mismatch (expected %s, got %s)",
|
||||
scriptTypeToString(to->type), scriptTypeToString(from->type) );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Check if two types are equivalent
|
||||
* Means: Their data can be copied without conversion.
|
||||
* I.e. strings are NOT equivalent to anything but strings, even though they can be converted
|
||||
|
@ -1240,14 +1163,15 @@ static inline void createVarEnvironment(SCRIPT_CONTEXT *psContext, UDWORD eventI
|
|||
varEnvironment[callDepth] = (INTERP_VAL *)malloc(sizeof(INTERP_VAL) * numEventVars);
|
||||
|
||||
// create environment
|
||||
memcpy(varEnvironment[callDepth], psContext->psCode->ppsLocalVars[eventIndex], sizeof(INTERP_VAL) * numEventVars);
|
||||
memcpy(varEnvironment[callDepth], psContext->psCode->ppsLocalVarVal[eventIndex], sizeof(INTERP_VAL) * numEventVars);
|
||||
|
||||
// allocate new space for strings to preserve original ones
|
||||
for (i = 0; i < numEventVars; i++)
|
||||
{
|
||||
if (!interpInitValue(varEnvironment[callDepth][i].type, &varEnvironment[callDepth][i]))
|
||||
if (varEnvironment[callDepth][i].type == VAL_STRING)
|
||||
{
|
||||
debug(LOG_ERROR, "createVarEnvironment: failed to init local var");
|
||||
varEnvironment[callDepth][i].v.sval = (char*)malloc(MAXSTRLEN);
|
||||
strcpy( varEnvironment[callDepth][i].v.sval, "" ); //initialize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,9 +163,6 @@ typedef enum _op_code
|
|||
#define ARRAY_DIMENSION_SHIFT 20
|
||||
#define ARRAY_DIMENSION_MASK 0x00f00000
|
||||
|
||||
#define VAR_COPY_DEEP true
|
||||
#define VAR_COPY_FLAT false
|
||||
|
||||
/* The possible storage types for a variable */
|
||||
typedef enum _storage_type
|
||||
{
|
||||
|
@ -248,11 +245,13 @@ typedef struct _script_code
|
|||
UDWORD arraySize; // the number of elements in all the defined arrays
|
||||
INTERP_TYPE *pGlobals; // Types of the global variables
|
||||
|
||||
UDWORD *numLocalVars; //number of local vars each event has
|
||||
INTERP_VAL **ppsLocalVars; //storage for local vars
|
||||
|
||||
INTERP_TYPE **ppsLocalVars; //storage for local vars (type)
|
||||
UDWORD *numLocalVars; //number of local vars each event has
|
||||
INTERP_VAL **ppsLocalVarVal; //Values of the local vars used during interpreting process
|
||||
UDWORD *numParams; //number of arguments this event has
|
||||
|
||||
|
||||
VAR_DEBUG *psVarDebug; // The names and storage types of variables
|
||||
ARRAY_DATA *psArrayInfo; // The sizes of the program arrays
|
||||
ARRAY_DEBUG *psArrayDebug; // Debug info for the arrays
|
||||
|
@ -285,10 +284,6 @@ extern BOOL interpProcessorActive(void);
|
|||
/* Output script call stack trace */
|
||||
extern void scrOutputCallTrace(void);
|
||||
|
||||
extern BOOL interpCopyValue(INTERP_VAL *to, INTERP_VAL *from, BOOL deep);
|
||||
extern BOOL interpInitValue(INTERP_TYPE type, INTERP_VAL *value);
|
||||
extern void interpCleanValue(INTERP_VAL *value);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -81,10 +81,18 @@ void scriptFreeCode(SCRIPT_CODE *psCode)
|
|||
//free strings for event i
|
||||
for(j=0; j < psCode->numLocalVars[i]; j++)
|
||||
{
|
||||
interpCleanValue(&psCode->ppsLocalVars[i][j]);
|
||||
|
||||
if(psCode->ppsLocalVarVal[i][j].type == VAL_STRING) //if a string
|
||||
{
|
||||
if(psCode->ppsLocalVarVal[i][j].v.sval != NULL) //doublecheck..
|
||||
{
|
||||
free(psCode->ppsLocalVarVal[i][j].v.sval); //free string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(psCode->ppsLocalVars[i]); // free pointer to event i local vars
|
||||
free(psCode->ppsLocalVars[i]);
|
||||
free(psCode->ppsLocalVarVal[i]); //free pointer to event i local vars
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,6 +160,9 @@ void scriptFreeCode(SCRIPT_CODE *psCode)
|
|||
if(psCode->ppsLocalVars != NULL)
|
||||
free(psCode->ppsLocalVars);
|
||||
|
||||
if(psCode->ppsLocalVarVal != NULL)
|
||||
free(psCode->ppsLocalVarVal);
|
||||
|
||||
psCode->numEvents = 0;
|
||||
|
||||
free(psCode);
|
||||
|
|
|
@ -1992,14 +1992,11 @@ script: header var_list
|
|||
ALLOC_PROG(psFinalProg, size, psCurrBlock->pCode,
|
||||
numVars, numArrays, numTriggers, numEvents);
|
||||
|
||||
debug(LOG_SCRIPT, "allocated space for %d events", numEvents);
|
||||
|
||||
//store local vars
|
||||
psFinalProg->numLocalVars = (UDWORD *)malloc(sizeof(UDWORD) * numEvents); //how many local vars each event has
|
||||
|
||||
//allocate array for holding an array of local vars for each event
|
||||
psFinalProg->ppsLocalVars = (INTERP_VAL **)malloc(sizeof(INTERP_VAL*) * numEvents);
|
||||
|
||||
psFinalProg->ppsLocalVars = (INTERP_TYPE **)malloc(sizeof(INTERP_TYPE*) * numEvents);
|
||||
psFinalProg->ppsLocalVarVal = NULL;
|
||||
psFinalProg->numLocalVars = (UDWORD *)malloc(sizeof(UDWORD) * numEvents); //how many local vars each event has
|
||||
psFinalProg->numParams = (UDWORD *)malloc(sizeof(UDWORD) * numEvents); //how many arguments each event has
|
||||
|
||||
for(psEvent = psEvents, i = 0; psEvent; psEvent = psEvent->psNext, i++)
|
||||
|
@ -2012,11 +2009,11 @@ script: header var_list
|
|||
if(numEventLocalVars[i] > 0)
|
||||
{
|
||||
unsigned int j;
|
||||
INTERP_VAL * pCurEvLocalVars = (INTERP_VAL*)malloc(sizeof(INTERP_VAL) * numEventLocalVars[i]);
|
||||
INTERP_TYPE * pCurEvLocalVars = (INTERP_TYPE*)malloc(sizeof(INTERP_TYPE) * numEventLocalVars[i]);
|
||||
|
||||
for(psCurr = psLocalVarsB[i], j = 0; psCurr != NULL; psCurr = psCurr->psNext, j++)
|
||||
{
|
||||
interpInitValue(psCurr->type, &pCurEvLocalVars[numEventLocalVars[i] - j - 1]);
|
||||
pCurEvLocalVars[numEventLocalVars[i] - j - 1] = psCurr->type; //save type, order is reversed
|
||||
}
|
||||
|
||||
psFinalProg->ppsLocalVars[i] = pCurEvLocalVars;
|
||||
|
|
|
@ -48,20 +48,20 @@ typedef struct _stack_chunk
|
|||
INTERP_VAL *aVals;
|
||||
UDWORD size;
|
||||
|
||||
struct _stack_chunk *psNext, *psPrev;
|
||||
struct _stack_chunk *psNext, *psPrev;
|
||||
} STACK_CHUNK;
|
||||
|
||||
/* The first chunk of the stack */
|
||||
static STACK_CHUNK *psStackBase = NULL;
|
||||
static STACK_CHUNK *psStackBase=NULL;
|
||||
|
||||
/* The current stack chunk */
|
||||
static STACK_CHUNK *psCurrChunk = NULL;
|
||||
static STACK_CHUNK *psCurrChunk=NULL;
|
||||
|
||||
/* The current free entry on the current stack chunk */
|
||||
static UDWORD currEntry = 0;
|
||||
static UDWORD currEntry=0;
|
||||
|
||||
/* Get rid of the top value(s) without returning it */
|
||||
static inline BOOL stackReduce(unsigned int numItems);
|
||||
/* Get rid of the top value without returning it */
|
||||
static inline BOOL stackRemoveTop(void);
|
||||
|
||||
|
||||
/* Check if the stack is empty */
|
||||
|
@ -112,13 +112,35 @@ static BOOL stackNewChunk(UDWORD size)
|
|||
|
||||
|
||||
/* Push a value onto the stack */
|
||||
BOOL stackPush(INTERP_VAL *psVal)
|
||||
BOOL stackPush(INTERP_VAL *psVal)
|
||||
{
|
||||
/* Store the value in the stack - psCurrChunk/currEntry always point to
|
||||
valid space */
|
||||
|
||||
interpInitValue(psVal->type, &psCurrChunk->aVals[currEntry]);
|
||||
interpCopyValue(&psCurrChunk->aVals[currEntry], psVal, VAR_COPY_DEEP);
|
||||
/* String support: Copy the string, otherwise the stack will operate directly on the
|
||||
original string (like & opcode will actually store the result in the first
|
||||
variable which would point to the original string) */
|
||||
if(psVal->type == VAL_STRING) //pushing string
|
||||
{
|
||||
/* strings should already have memory allocated */
|
||||
if(psCurrChunk->aVals[currEntry].type != VAL_STRING) //needs to have memory allocated for string
|
||||
psCurrChunk->aVals[currEntry].v.sval = (char*)malloc(MAXSTRLEN);
|
||||
|
||||
strcpy(psCurrChunk->aVals[currEntry].v.sval, psVal->v.sval); //copy string to stack
|
||||
psCurrChunk->aVals[currEntry].type = VAL_STRING;
|
||||
}
|
||||
else /* pushing non-string */
|
||||
{
|
||||
/* free stack var allocated string memory, if stack var used to be of type VAL_STRING */
|
||||
if(psCurrChunk->aVals[currEntry].type == VAL_STRING)
|
||||
{
|
||||
free(psCurrChunk->aVals[currEntry].v.sval); //don't need it anymore
|
||||
psCurrChunk->aVals[currEntry].v.sval = NULL;
|
||||
}
|
||||
|
||||
/* copy type/data as union */
|
||||
memcpy(&(psCurrChunk->aVals[currEntry]), psVal, sizeof(INTERP_VAL));
|
||||
}
|
||||
|
||||
/* Now update psCurrChunk and currEntry */
|
||||
currEntry++;
|
||||
|
@ -137,8 +159,9 @@ BOOL stackPush(INTERP_VAL *psVal)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* Pop a value off the stack */
|
||||
BOOL stackPop(INTERP_VAL *psVal)
|
||||
BOOL stackPop(INTERP_VAL *psVal)
|
||||
{
|
||||
if (stackEmpty())
|
||||
{
|
||||
|
@ -148,20 +171,25 @@ BOOL stackPop(INTERP_VAL *psVal)
|
|||
}
|
||||
|
||||
/* move the stack pointer down one */
|
||||
if (!stackReduce(1))
|
||||
if (currEntry == 0)
|
||||
{
|
||||
return false;
|
||||
/* have to move onto the previous chunk. */
|
||||
psCurrChunk = psCurrChunk->psPrev;
|
||||
currEntry = psCurrChunk->size -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
currEntry--;
|
||||
}
|
||||
|
||||
/* copy the entire value off the stack */
|
||||
memcpy(psVal, &psCurrChunk->aVals[currEntry], sizeof(*psVal));
|
||||
memcpy(psVal, &(psCurrChunk->aVals[currEntry]), sizeof(INTERP_VAL));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Return pointer to the top value without poping it */
|
||||
BOOL stackPeekTop(INTERP_VAL **ppsVal)
|
||||
BOOL stackPeekTop(INTERP_VAL **ppsVal)
|
||||
{
|
||||
if ((psCurrChunk->psPrev == NULL) && (currEntry == 0))
|
||||
{
|
||||
|
@ -191,9 +219,9 @@ BOOL stackPeekTop(INTERP_VAL **ppsVal)
|
|||
|
||||
|
||||
/* Pop a value off the stack, checking that the type matches what is passed in */
|
||||
BOOL stackPopType(INTERP_VAL *psVal)
|
||||
BOOL stackPopType(INTERP_VAL *psVal)
|
||||
{
|
||||
INTERP_VAL *psTop;
|
||||
INTERP_VAL *psTop;
|
||||
|
||||
if ((psCurrChunk->psPrev == NULL) && (currEntry == 0))
|
||||
{
|
||||
|
@ -453,6 +481,8 @@ BOOL stackPushResult(INTERP_TYPE type, INTERP_VAL *result)
|
|||
*/
|
||||
BOOL stackPeek(INTERP_VAL *psVal, UDWORD index)
|
||||
{
|
||||
STACK_CHUNK *psCurr;
|
||||
|
||||
if (index < currEntry)
|
||||
{
|
||||
/* Looking at entry on current chunk */
|
||||
|
@ -461,8 +491,6 @@ BOOL stackPeek(INTERP_VAL *psVal, UDWORD index)
|
|||
}
|
||||
else
|
||||
{
|
||||
STACK_CHUNK *psCurr;
|
||||
|
||||
/* Have to work down the previous chunks to find the entry */
|
||||
index -= currEntry;
|
||||
|
||||
|
@ -474,8 +502,10 @@ BOOL stackPeek(INTERP_VAL *psVal, UDWORD index)
|
|||
memcpy(psVal, &(psCurr->aVals[psCurr->size - 1 - index]), sizeof(INTERP_VAL));
|
||||
return true;
|
||||
}
|
||||
|
||||
index -= psCurr->size;
|
||||
else
|
||||
{
|
||||
index -= psCurr->size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -806,7 +836,7 @@ BOOL stackUnaryOp(OPCODE opcode)
|
|||
psVal->v.ival++;
|
||||
|
||||
/* Just get rid of the variable pointer, since already increased it */
|
||||
if (!stackReduce(1))
|
||||
if (!stackRemoveTop())
|
||||
{
|
||||
debug( LOG_ERROR, "stackUnaryOpcode: OP_INC: could not pop" );
|
||||
return false;
|
||||
|
@ -831,7 +861,7 @@ BOOL stackUnaryOp(OPCODE opcode)
|
|||
psVal->v.ival--;
|
||||
|
||||
/* Just get rid of the variable pointer, since already decreased it */
|
||||
if (!stackReduce(1))
|
||||
if (!stackRemoveTop())
|
||||
{
|
||||
debug( LOG_ERROR, "stackUnaryOpcode: OP_DEC: could not pop" );
|
||||
return false;
|
||||
|
@ -880,7 +910,6 @@ BOOL stackUnaryOp(OPCODE opcode)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
BOOL stackCastTop(INTERP_TYPE neededType)
|
||||
{
|
||||
INTERP_VAL *pTop;
|
||||
|
@ -976,12 +1005,14 @@ BOOL stackInitialise(void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* Shutdown the stack */
|
||||
void stackShutDown(void)
|
||||
{
|
||||
STACK_CHUNK *psCurr, *psNext;
|
||||
STACK_CHUNK *psCurr, *psNext;
|
||||
UDWORD i;
|
||||
|
||||
if (!stackEmpty())
|
||||
if ((psCurrChunk != psStackBase) && (currEntry != 0))
|
||||
{
|
||||
debug( LOG_NEVER, "stackShutDown: stack is not empty on shutdown" );
|
||||
}
|
||||
|
@ -989,56 +1020,52 @@ void stackShutDown(void)
|
|||
for(psCurr = psStackBase; psCurr != NULL; psCurr = psNext)
|
||||
{
|
||||
psNext = psCurr->psNext;
|
||||
|
||||
/* Free strings */
|
||||
for(i=0; i< psCurr->size; i++) //go through all values on this chunk
|
||||
{
|
||||
if(psCurr->aVals[i].type == VAL_STRING)
|
||||
{
|
||||
if(psCurr->aVals[i].v.sval != NULL) //FIXME: seems to be causing problems sometimes
|
||||
{
|
||||
debug(LOG_WZ, "freeing '%s' ", psCurr->aVals[i].v.sval);
|
||||
free(psCurr->aVals[i].v.sval);
|
||||
psCurr->aVals[i].v.sval = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_SCRIPT, "stackShutDown: VAL_STRING with null pointer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(psCurr->aVals);
|
||||
free(psCurr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get rid of the top value(s) without returning it */
|
||||
static inline BOOL stackReduce(unsigned int numItems)
|
||||
/* Get rid of the top value without returning it */
|
||||
static inline BOOL stackRemoveTop(void)
|
||||
{
|
||||
if (stackEmpty())
|
||||
if ((psCurrChunk->psPrev == NULL) && (currEntry == 0))
|
||||
{
|
||||
debug(LOG_ERROR, "stackReduce: stack empty");
|
||||
ASSERT( false, "stackReduce: stack empty" );
|
||||
debug(LOG_ERROR, "stackRemoveTop: stack empty");
|
||||
ASSERT( false, "stackRemoveTop: stack empty" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the position of the first item, and set
|
||||
// the stack top to it
|
||||
if (numItems <= currEntry)
|
||||
/* move the stack pointer down one */
|
||||
if (currEntry == 0)
|
||||
{
|
||||
// items are all on current chunk
|
||||
currEntry = currEntry - numItems;
|
||||
/* have to move onto the previous chunk. */
|
||||
psCurrChunk = psCurrChunk->psPrev;
|
||||
currEntry = psCurrChunk->size -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Have to work down the previous chunks to find the first item
|
||||
unsigned int items = numItems - currEntry;
|
||||
STACK_CHUNK *psCurr;
|
||||
|
||||
for(psCurr = psCurrChunk->psPrev; psCurr != NULL; psCurr = psCurr->psPrev)
|
||||
{
|
||||
if (items <= psCurr->size)
|
||||
{
|
||||
// found the first item
|
||||
currEntry = psCurr->size - items;
|
||||
psCurrChunk = psCurr;
|
||||
break;
|
||||
}
|
||||
|
||||
items -= psCurr->size;
|
||||
}
|
||||
|
||||
if (!psCurr)
|
||||
{
|
||||
debug( LOG_ERROR, "stackReduce: not enough parameters on stack" );
|
||||
ASSERT( false, "stackReduce: not enough parameters on stack" );
|
||||
return false;
|
||||
}
|
||||
currEntry--;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1073,7 @@ static inline BOOL stackReduce(unsigned int numItems)
|
|||
/* Reset the stack to an empty state */
|
||||
void stackReset(void)
|
||||
{
|
||||
ASSERT(stackEmpty(),
|
||||
ASSERT( ((psCurrChunk == psStackBase) && (currEntry == 0)),
|
||||
"stackReset: stack is not empty" );
|
||||
|
||||
psCurrChunk = psStackBase;
|
||||
|
|
|
@ -37,13 +37,16 @@ extern BOOL stackInitialise(void);
|
|||
extern void stackShutDown(void);
|
||||
|
||||
/* Push a value onto the stack */
|
||||
extern BOOL stackPush(INTERP_VAL *psVal);
|
||||
extern BOOL stackPush(INTERP_VAL *psVal);
|
||||
|
||||
/* Pop a value off the stack */
|
||||
extern BOOL stackPop(INTERP_VAL *psVal);
|
||||
extern BOOL stackPop(INTERP_VAL *psVal);
|
||||
|
||||
/* Return pointer to the top value without poping it */
|
||||
extern BOOL stackPeekTop(INTERP_VAL **ppsVal);
|
||||
|
||||
/* Pop a value off the stack, checking that the type matches what is passed in */
|
||||
extern BOOL stackPopType(INTERP_VAL *psVal);
|
||||
extern BOOL stackPopType(INTERP_VAL *psVal);
|
||||
|
||||
/* Look at a value on the stack without removing it.
|
||||
* index is how far down the stack to look.
|
||||
|
|
Loading…
Reference in New Issue