diff --git a/Engine/source/console/compiledEval.cpp b/Engine/source/console/compiledEval.cpp index afa1c5295..f74ada2ae 100644 --- a/Engine/source/console/compiledEval.cpp +++ b/Engine/source/console/compiledEval.cpp @@ -470,11 +470,11 @@ ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thi dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer), "%s(", thisFunctionName); } - for (i = 0; i < wantedArgc; i++) + for(i = 0; i < wantedArgc; i++) { - dStrcat(traceBuffer, argv[i + 1]); - if (i != wantedArgc - 1) - dStrcat(traceBuffer, ", "); + dStrcat(traceBuffer, argv[i+1]); + if(i != wantedArgc - 1) + dStrcat(traceBuffer, ", "); } dStrcat(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 - // either nothing or argv[] which we just copied - CSTK.resetFrame(); + bool doResetValueStack = !gEvalState.mResetLocked; + gEvalState.mResetLocked = true; + + 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 // so that the push and pop frames are always balanced. @@ -1817,7 +1824,7 @@ breakContinue: ConsoleValueRef ret; if(nsEntry->mFunctionOffset) ret = nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage); - + STR.popFrame(); // Functions are assumed to return strings, so look ahead to see if we can skip the conversion if(code[ip] == OP_STR_TO_UINT) @@ -1837,7 +1844,7 @@ breakContinue: } else STR.setStringValue((const char*)ret); - + // This will clear everything including returnValue CSTK.popFrame(); STR.clearFunctionOffset(); @@ -2219,15 +2226,7 @@ execFinished: Con::printf("%s", traceBuffer); } } - else - { - delete[] globalStrings; - globalStringsMaxLen = 0; - delete[] globalFloats; - globalStrings = NULL; - globalFloats = NULL; - } smCurrentCodeBlock = saveCodeBlock; if(saveCodeBlock && saveCodeBlock->name) { @@ -2235,6 +2234,13 @@ execFinished: 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(); #ifdef TORQUE_DEBUG diff --git a/Engine/source/console/consoleInternal.cpp b/Engine/source/console/consoleInternal.cpp index f8f4eb046..70b8edcd0 100644 --- a/Engine/source/console/consoleInternal.cpp +++ b/Engine/source/console/consoleInternal.cpp @@ -796,6 +796,7 @@ ExprEvalState::ExprEvalState() currentVariable = NULL; mStackDepth = 0; stack.reserve( 64 ); + mShouldReset = false; } ExprEvalState::~ExprEvalState() diff --git a/Engine/source/console/consoleInternal.h b/Engine/source/console/consoleInternal.h index e6dd6b99d..23d3b2e95 100644 --- a/Engine/source/console/consoleInternal.h +++ b/Engine/source/console/consoleInternal.h @@ -468,6 +468,8 @@ public: bool traceOn; U32 mStackDepth; + bool mShouldReset; ///< Designates if the value stack should be reset + bool mResetLocked; ///< mShouldReset will be set at the end ExprEvalState(); ~ExprEvalState(); diff --git a/Engine/source/console/stringStack.cpp b/Engine/source/console/stringStack.cpp index e57445657..23215eaec 100644 --- a/Engine/source/console/stringStack.cpp +++ b/Engine/source/console/stringStack.cpp @@ -162,7 +162,7 @@ ConsoleValue* ConsoleValueStack::pop() void ConsoleValueStack::pushFrame() { - //Con::printf("CSTK pushFrame"); + //Con::printf("CSTK pushFrame[%i] (%i)", mFrame, mStackPos); mStackFrames[mFrame++] = mStackPos; } @@ -181,6 +181,12 @@ void ConsoleValueStack::resetFrame() //Con::printf("CSTK resetFrame to %i", mStackPos); } +void ConsoleValueStack::clearFrames() +{ + mStackPos = 0; + mFrame = 0; +} + void ConsoleValueStack::popFrame() { //Con::printf("CSTK popFrame"); diff --git a/Engine/source/console/stringStack.h b/Engine/source/console/stringStack.h index 3e4d4d3ce..2d36aa482 100644 --- a/Engine/source/console/stringStack.h +++ b/Engine/source/console/stringStack.h @@ -74,6 +74,7 @@ struct StringStack mBuffer = (char *) dRealloc(mBuffer, mBufferSize); } } + void validateArgBufferSize(U32 size) { if(size > mArgBufferSize) @@ -82,6 +83,7 @@ struct StringStack mArgBuffer = (char *) dRealloc(mArgBuffer, mArgBufferSize); } } + StringStack() { mBufferSize = 0; @@ -95,6 +97,8 @@ struct StringStack mFunctionOffset = 0; validateBufferSize(8192); validateArgBufferSize(2048); + dMemset(mBuffer, '\0', mBufferSize); + dMemset(mArgBuffer, '\0', mArgBufferSize); } ~StringStack() { @@ -141,6 +145,7 @@ struct StringStack /// Clear the function offset. void clearFunctionOffset() { + //Con::printf("StringStack mFunctionOffset = 0 (from %i)", mFunctionOffset); mFunctionOffset = 0; } @@ -262,9 +267,9 @@ struct StringStack return ret; } - void pushFrame() { + //Con::printf("StringStack pushFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize); mFrameOffsets[mNumFrames++] = mStartStackSize; mStartOffsets[mStartStackSize++] = mStart; mStart += ReturnBufferSpace; @@ -273,11 +278,22 @@ struct StringStack void popFrame() { + //Con::printf("StringStack popFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize); mStartStackSize = mFrameOffsets[--mNumFrames]; mStart = mStartOffsets[mStartStackSize]; 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. void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false); }; @@ -309,6 +325,7 @@ public: void popFrame(); void resetFrame(); + void clearFrames(); void getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame = false);