Merge pull request #1026 from jamesu/fix_console_stack

Fix issue where console stack values were getting overwritten
This commit is contained in:
Daniel Buckmaster 2014-12-21 19:02:20 +11:00
commit 7916ff369b
5 changed files with 52 additions and 19 deletions

View file

@ -470,11 +470,11 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer), dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer),
"%s(", thisFunctionName); "%s(", thisFunctionName);
} }
for (i = 0; i < wantedArgc; i++) for(i = 0; i < wantedArgc; i++)
{ {
dStrcat(traceBuffer, argv[i + 1]); dStrcat(traceBuffer, argv[i+1]);
if (i != wantedArgc - 1) if(i != wantedArgc - 1)
dStrcat(traceBuffer, ", "); dStrcat(traceBuffer, ", ");
} }
dStrcat(traceBuffer, ")"); dStrcat(traceBuffer, ")");
Con::printf("%s", traceBuffer); Con::printf("%s", traceBuffer);
@ -533,9 +533,16 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi
} }
} }
// Reset the console stack frame which at this point will contain bool doResetValueStack = !gEvalState.mResetLocked;
// either nothing or argv[] which we just copied gEvalState.mResetLocked = true;
CSTK.resetFrame();
if (gEvalState.mShouldReset)
{
// Ensure all stacks are clean in case anything became unbalanced during the previous execution
STR.clearFrames();
CSTK.clearFrames();
gEvalState.mShouldReset = false;
}
// Grab the state of the telenet debugger here once // Grab the state of the telenet debugger here once
// so that the push and pop frames are always balanced. // so that the push and pop frames are always balanced.
@ -2219,15 +2226,7 @@ execFinished:
Con::printf("%s", traceBuffer); Con::printf("%s", traceBuffer);
} }
} }
else
{
delete[] globalStrings;
globalStringsMaxLen = 0;
delete[] globalFloats;
globalStrings = NULL;
globalFloats = NULL;
}
smCurrentCodeBlock = saveCodeBlock; smCurrentCodeBlock = saveCodeBlock;
if(saveCodeBlock && saveCodeBlock->name) if(saveCodeBlock && saveCodeBlock->name)
{ {
@ -2235,6 +2234,13 @@ execFinished:
Con::gCurrentRoot = saveCodeBlock->modPath; Con::gCurrentRoot = saveCodeBlock->modPath;
} }
// Mark the reset flag for the next run if we've finished execution
if (doResetValueStack)
{
gEvalState.mShouldReset = true;
gEvalState.mResetLocked = false;
}
decRefCount(); decRefCount();
#ifdef TORQUE_DEBUG #ifdef TORQUE_DEBUG

View file

@ -796,6 +796,8 @@ ExprEvalState::ExprEvalState()
currentVariable = NULL; currentVariable = NULL;
mStackDepth = 0; mStackDepth = 0;
stack.reserve( 64 ); stack.reserve( 64 );
mShouldReset = false;
mResetLocked = false;
} }
ExprEvalState::~ExprEvalState() ExprEvalState::~ExprEvalState()

View file

@ -468,6 +468,8 @@ public:
bool traceOn; bool traceOn;
U32 mStackDepth; U32 mStackDepth;
bool mShouldReset; ///< Designates if the value stack should be reset
bool mResetLocked; ///< mShouldReset will be set at the end
ExprEvalState(); ExprEvalState();
~ExprEvalState(); ~ExprEvalState();

View file

@ -162,7 +162,7 @@ ConsoleValue* ConsoleValueStack::pop()
void ConsoleValueStack::pushFrame() void ConsoleValueStack::pushFrame()
{ {
//Con::printf("CSTK pushFrame"); //Con::printf("CSTK pushFrame[%i] (%i)", mFrame, mStackPos);
mStackFrames[mFrame++] = mStackPos; mStackFrames[mFrame++] = mStackPos;
} }
@ -181,6 +181,12 @@ void ConsoleValueStack::resetFrame()
//Con::printf("CSTK resetFrame to %i", mStackPos); //Con::printf("CSTK resetFrame to %i", mStackPos);
} }
void ConsoleValueStack::clearFrames()
{
mStackPos = 0;
mFrame = 0;
}
void ConsoleValueStack::popFrame() void ConsoleValueStack::popFrame()
{ {
//Con::printf("CSTK popFrame"); //Con::printf("CSTK popFrame");

View file

@ -74,6 +74,7 @@ struct StringStack
mBuffer = (char *) dRealloc(mBuffer, mBufferSize); mBuffer = (char *) dRealloc(mBuffer, mBufferSize);
} }
} }
void validateArgBufferSize(U32 size) void validateArgBufferSize(U32 size)
{ {
if(size > mArgBufferSize) if(size > mArgBufferSize)
@ -82,6 +83,7 @@ struct StringStack
mArgBuffer = (char *) dRealloc(mArgBuffer, mArgBufferSize); mArgBuffer = (char *) dRealloc(mArgBuffer, mArgBufferSize);
} }
} }
StringStack() StringStack()
{ {
mBufferSize = 0; mBufferSize = 0;
@ -95,6 +97,8 @@ struct StringStack
mFunctionOffset = 0; mFunctionOffset = 0;
validateBufferSize(8192); validateBufferSize(8192);
validateArgBufferSize(2048); validateArgBufferSize(2048);
dMemset(mBuffer, '\0', mBufferSize);
dMemset(mArgBuffer, '\0', mArgBufferSize);
} }
~StringStack() ~StringStack()
{ {
@ -141,6 +145,7 @@ struct StringStack
/// Clear the function offset. /// Clear the function offset.
void clearFunctionOffset() void clearFunctionOffset()
{ {
//Con::printf("StringStack mFunctionOffset = 0 (from %i)", mFunctionOffset);
mFunctionOffset = 0; mFunctionOffset = 0;
} }
@ -262,9 +267,9 @@ struct StringStack
return ret; return ret;
} }
void pushFrame() void pushFrame()
{ {
//Con::printf("StringStack pushFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
mFrameOffsets[mNumFrames++] = mStartStackSize; mFrameOffsets[mNumFrames++] = mStartStackSize;
mStartOffsets[mStartStackSize++] = mStart; mStartOffsets[mStartStackSize++] = mStart;
mStart += ReturnBufferSpace; mStart += ReturnBufferSpace;
@ -273,11 +278,22 @@ struct StringStack
void popFrame() void popFrame()
{ {
//Con::printf("StringStack popFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
mStartStackSize = mFrameOffsets[--mNumFrames]; mStartStackSize = mFrameOffsets[--mNumFrames];
mStart = mStartOffsets[mStartStackSize]; mStart = mStartOffsets[mStartStackSize];
mLen = 0; mLen = 0;
} }
void clearFrames()
{
//Con::printf("StringStack clearFrames");
mNumFrames = 0;
mStart = 0;
mLen = 0;
mStartStackSize = 0;
mFunctionOffset = 0;
}
/// Get the arguments for a function call from the stack. /// Get the arguments for a function call from the stack.
void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false); void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false);
}; };
@ -309,6 +325,7 @@ public:
void popFrame(); void popFrame();
void resetFrame(); void resetFrame();
void clearFrames();
void getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame = false); void getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame = false);