mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 03:33:48 +00:00
Console Refactor
This commit is contained in:
parent
626de074cc
commit
89b0c7f73b
89 changed files with 1883 additions and 1553 deletions
|
|
@ -25,13 +25,11 @@
|
|||
#include "platform/platform.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include "console/ast.h"
|
||||
#include "core/tAlgorithm.h"
|
||||
|
||||
#include "core/strings/findMatch.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/compiler.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
//#define DEBUG_SPEW
|
||||
|
|
@ -375,18 +373,16 @@ Dictionary::Dictionary()
|
|||
#pragma warning( disable : 4355 )
|
||||
ownHashTable(this), // Warning with VC++ but this is safe.
|
||||
#pragma warning( default : 4355 )
|
||||
exprState(NULL),
|
||||
scopeName(NULL),
|
||||
scopeNamespace(NULL),
|
||||
code(NULL),
|
||||
module(NULL),
|
||||
ip(0)
|
||||
{
|
||||
setState(NULL);
|
||||
}
|
||||
|
||||
void Dictionary::setState(ExprEvalState *state, Dictionary* ref)
|
||||
void Dictionary::setState(Dictionary* ref)
|
||||
{
|
||||
exprState = state;
|
||||
|
||||
if (ref)
|
||||
{
|
||||
hashTable = ref->hashTable;
|
||||
|
|
@ -439,7 +435,7 @@ void Dictionary::reset()
|
|||
|
||||
scopeName = NULL;
|
||||
scopeNamespace = NULL;
|
||||
code = NULL;
|
||||
module = NULL;
|
||||
ip = 0;
|
||||
}
|
||||
|
||||
|
|
@ -680,158 +676,15 @@ void Dictionary::validate()
|
|||
"Dictionary::validate() - Dictionary not owner of own hashtable!");
|
||||
}
|
||||
|
||||
void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns, S32 registerCount)
|
||||
Con::Module* Con::findScriptModuleForFile(const char* fileName)
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
|
||||
Platform::outputDebugString("[ConsoleInternal] Pushing new frame for '%s' at %i",
|
||||
frameName, mStackDepth);
|
||||
#endif
|
||||
|
||||
if (mStackDepth + 1 > stack.size())
|
||||
for (Con::Module* module : gScriptModules)
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame");
|
||||
#endif
|
||||
|
||||
stack.push_back(new Dictionary);
|
||||
if (module->getName() == fileName) {
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary& newFrame = *(stack[mStackDepth]);
|
||||
newFrame.setState(this);
|
||||
|
||||
newFrame.scopeName = frameName;
|
||||
newFrame.scopeNamespace = ns;
|
||||
|
||||
mStackDepth++;
|
||||
currentVariable = NULL;
|
||||
|
||||
AssertFatal(!newFrame.getCount(), "ExprEvalState::pushFrame - Dictionary not empty!");
|
||||
|
||||
ConsoleValue* consoleValArray = new ConsoleValue[registerCount]();
|
||||
localStack.push_back(ConsoleValueFrame(consoleValArray, false));
|
||||
currentRegisterArray = &localStack.last();
|
||||
|
||||
AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size()));
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ExprEvalState::popFrame()
|
||||
{
|
||||
AssertFatal(mStackDepth > 0, "ExprEvalState::popFrame - Stack Underflow!");
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
|
||||
Platform::outputDebugString("[ConsoleInternal] Popping %sframe at %i",
|
||||
getCurrentFrame().isOwner() ? "" : "shared ", mStackDepth - 1);
|
||||
#endif
|
||||
|
||||
mStackDepth--;
|
||||
stack[mStackDepth]->reset();
|
||||
currentVariable = NULL;
|
||||
|
||||
const ConsoleValueFrame& frame = localStack.last();
|
||||
localStack.pop_back();
|
||||
if (!frame.isReference)
|
||||
delete[] frame.values;
|
||||
|
||||
currentRegisterArray = localStack.size() ? &localStack.last() : NULL;
|
||||
|
||||
AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size()));
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ExprEvalState::pushFrameRef(S32 stackIndex)
|
||||
{
|
||||
AssertFatal(stackIndex >= 0 && stackIndex < mStackDepth, "You must be asking for a valid frame!");
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
|
||||
Platform::outputDebugString("[ConsoleInternal] Cloning frame from %i to %i",
|
||||
stackIndex, mStackDepth);
|
||||
#endif
|
||||
|
||||
if (mStackDepth + 1 > stack.size())
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame");
|
||||
#endif
|
||||
|
||||
stack.push_back(new Dictionary);
|
||||
}
|
||||
|
||||
Dictionary& newFrame = *(stack[mStackDepth]);
|
||||
newFrame.setState(this, stack[stackIndex]);
|
||||
|
||||
mStackDepth++;
|
||||
currentVariable = NULL;
|
||||
|
||||
ConsoleValue* values = localStack[stackIndex].values;
|
||||
localStack.push_back(ConsoleValueFrame(values, true));
|
||||
currentRegisterArray = &localStack.last();
|
||||
|
||||
AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size()));
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ExprEvalState::pushDebugFrame(S32 stackIndex)
|
||||
{
|
||||
pushFrameRef(stackIndex);
|
||||
|
||||
Dictionary& newFrame = *(stack[mStackDepth - 1]);
|
||||
|
||||
// debugger needs to know this info...
|
||||
newFrame.scopeName = stack[stackIndex]->scopeName;
|
||||
newFrame.scopeNamespace = stack[stackIndex]->scopeNamespace;
|
||||
newFrame.code = stack[stackIndex]->code;
|
||||
newFrame.ip = stack[stackIndex]->ip;
|
||||
}
|
||||
|
||||
ExprEvalState::ExprEvalState()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION(stack);
|
||||
globalVars.setState(this);
|
||||
thisObject = NULL;
|
||||
traceOn = false;
|
||||
currentVariable = NULL;
|
||||
mStackDepth = 0;
|
||||
stack.reserve(64);
|
||||
mShouldReset = false;
|
||||
mResetLocked = false;
|
||||
copyVariable = NULL;
|
||||
currentRegisterArray = NULL;
|
||||
}
|
||||
|
||||
ExprEvalState::~ExprEvalState()
|
||||
{
|
||||
// Delete callframes.
|
||||
|
||||
while (!stack.empty())
|
||||
{
|
||||
delete stack.last();
|
||||
stack.decrement();
|
||||
}
|
||||
}
|
||||
|
||||
void ExprEvalState::validate()
|
||||
{
|
||||
AssertFatal(mStackDepth <= stack.size(),
|
||||
"ExprEvalState::validate() - Stack depth pointing beyond last stack frame!");
|
||||
|
||||
for (U32 i = 0; i < stack.size(); ++i)
|
||||
stack[i]->validate();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DefineEngineFunction(backtrace, void, (), ,
|
||||
|
|
@ -842,35 +695,37 @@ DefineEngineFunction(backtrace, void, (), ,
|
|||
{
|
||||
U32 totalSize = 1;
|
||||
|
||||
for (U32 i = 0; i < gEvalState.getStackDepth(); i++)
|
||||
for (U32 i = 0; i < Con::getFrameStack().size(); i++)
|
||||
{
|
||||
if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage)
|
||||
totalSize += dStrlen(gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) + 2;
|
||||
if (gEvalState.stack[i]->scopeName)
|
||||
totalSize += dStrlen(gEvalState.stack[i]->scopeName) + 3;
|
||||
if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName)
|
||||
totalSize += dStrlen(gEvalState.stack[i]->scopeNamespace->mName) + 2;
|
||||
const Con::ConsoleFrame* frame = Con::getStackFrame(i);
|
||||
if (frame->scopeNamespace && frame->scopeNamespace->mEntryList->mPackage)
|
||||
totalSize += dStrlen(frame->scopeNamespace->mEntryList->mPackage) + 2;
|
||||
if (frame->scopeName)
|
||||
totalSize += dStrlen(frame->scopeName) + 3;
|
||||
if (frame->scopeNamespace && frame->scopeNamespace->mName)
|
||||
totalSize += dStrlen(frame->scopeNamespace->mName) + 2;
|
||||
}
|
||||
|
||||
char *buf = Con::getReturnBuffer(totalSize);
|
||||
buf[0] = 0;
|
||||
for (U32 i = 0; i < gEvalState.getStackDepth(); i++)
|
||||
for (U32 i = 0; i < Con::getFrameStack().size(); i++)
|
||||
{
|
||||
const Con::ConsoleFrame* frame = Con::getStackFrame(i);
|
||||
dStrcat(buf, "->", totalSize);
|
||||
|
||||
if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage)
|
||||
if (frame->scopeNamespace && frame->scopeNamespace->mEntryList->mPackage)
|
||||
{
|
||||
dStrcat(buf, "[", totalSize);
|
||||
dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage, totalSize);
|
||||
dStrcat(buf, frame->scopeNamespace->mEntryList->mPackage, totalSize);
|
||||
dStrcat(buf, "]", totalSize);
|
||||
}
|
||||
if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName)
|
||||
if (frame->scopeNamespace && frame->scopeNamespace->mName)
|
||||
{
|
||||
dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mName, totalSize);
|
||||
dStrcat(buf, frame->scopeNamespace->mName, totalSize);
|
||||
dStrcat(buf, "::", totalSize);
|
||||
}
|
||||
if (gEvalState.stack[i]->scopeName)
|
||||
dStrcat(buf, gEvalState.stack[i]->scopeName, totalSize);
|
||||
if (frame->scopeName)
|
||||
dStrcat(buf, frame->scopeName, totalSize);
|
||||
}
|
||||
|
||||
Con::printf("BackTrace: %s", buf);
|
||||
|
|
@ -878,7 +733,7 @@ DefineEngineFunction(backtrace, void, (), ,
|
|||
|
||||
Namespace::Entry::Entry()
|
||||
{
|
||||
mCode = NULL;
|
||||
mModule = NULL;
|
||||
mType = InvalidFunctionType;
|
||||
mUsage = NULL;
|
||||
mHeader = NULL;
|
||||
|
|
@ -896,10 +751,10 @@ Namespace::Entry::Entry()
|
|||
|
||||
void Namespace::Entry::clear()
|
||||
{
|
||||
if (mCode)
|
||||
if (mModule)
|
||||
{
|
||||
mCode->decRefCount();
|
||||
mCode = NULL;
|
||||
mModule->decRefCount();
|
||||
mModule = NULL;
|
||||
}
|
||||
|
||||
// Clean up usage strings generated for script functions.
|
||||
|
|
@ -1233,15 +1088,15 @@ Namespace::Entry *Namespace::createLocalEntry(StringTableEntry name)
|
|||
return ent;
|
||||
}
|
||||
|
||||
void Namespace::addFunction(StringTableEntry name, CodeBlock *cb, U32 functionOffset, const char* usage, U32 lineNumber)
|
||||
void Namespace::addFunction(StringTableEntry name, Con::Module *cb, U32 functionOffset, const char* usage, U32 lineNumber)
|
||||
{
|
||||
Entry *ent = createLocalEntry(name);
|
||||
trashCache();
|
||||
|
||||
ent->mUsage = usage;
|
||||
ent->mCode = cb;
|
||||
ent->mModule = cb;
|
||||
ent->mFunctionOffset = functionOffset;
|
||||
ent->mCode->incRefCount();
|
||||
ent->mModule->incRefCount();
|
||||
ent->mType = Entry::ConsoleFunctionType;
|
||||
ent->mFunctionLineNumber = lineNumber;
|
||||
}
|
||||
|
|
@ -1366,9 +1221,7 @@ void Namespace::markGroup(const char* name, const char* usage)
|
|||
ent->cb.mGroupName = name;
|
||||
}
|
||||
|
||||
extern S32 executeBlock(StmtNode *block, ExprEvalState *state);
|
||||
|
||||
ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalState *state)
|
||||
ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, SimObject *thisObj)
|
||||
{
|
||||
STR.clearFunctionOffset();
|
||||
|
||||
|
|
@ -1376,7 +1229,7 @@ ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalSta
|
|||
{
|
||||
if (mFunctionOffset)
|
||||
{
|
||||
return std::move(mCode->exec(mFunctionOffset, argv[0].getString(), mNamespace, argc, argv, false, mPackage));
|
||||
return std::move(mModule->exec(mFunctionOffset, argv[0].getString(), mNamespace, argc, argv, false, mPackage).value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1406,21 +1259,21 @@ ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalSta
|
|||
{
|
||||
case StringCallbackType:
|
||||
{
|
||||
const char* str = cb.mStringCallbackFunc(state->thisObject, argc, argv);
|
||||
const char* str = cb.mStringCallbackFunc(thisObj, argc, argv);
|
||||
result.setString(str);
|
||||
break;
|
||||
}
|
||||
case IntCallbackType:
|
||||
result.setInt(cb.mIntCallbackFunc(state->thisObject, argc, argv));
|
||||
result.setInt(cb.mIntCallbackFunc(thisObj, argc, argv));
|
||||
break;
|
||||
case FloatCallbackType:
|
||||
result.setFloat(cb.mFloatCallbackFunc(state->thisObject, argc, argv));
|
||||
result.setFloat(cb.mFloatCallbackFunc(thisObj, argc, argv));
|
||||
break;
|
||||
case VoidCallbackType:
|
||||
cb.mVoidCallbackFunc(state->thisObject, argc, argv);
|
||||
cb.mVoidCallbackFunc(thisObj, argc, argv);
|
||||
break;
|
||||
case BoolCallbackType:
|
||||
result.setBool(cb.mBoolCallbackFunc(state->thisObject, argc, argv));
|
||||
result.setBool(cb.mBoolCallbackFunc(thisObj, argc, argv));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1704,7 +1557,7 @@ String Namespace::Entry::getArgumentsString() const
|
|||
|
||||
if (sFindArgumentListSubstring(mUsage, argListStart, argListEnd))
|
||||
str.append(argListStart, argListEnd - argListStart);
|
||||
else if (mType == ConsoleFunctionType && mCode)
|
||||
else if (mType == ConsoleFunctionType && mModule)
|
||||
{
|
||||
// This isn't correct but the nonsense console stuff is set up such that all
|
||||
// functions that have no function bodies are keyed to offset 0 to indicate "no code."
|
||||
|
|
@ -1716,7 +1569,7 @@ String Namespace::Entry::getArgumentsString() const
|
|||
if (!mFunctionOffset)
|
||||
return "()";
|
||||
|
||||
String args = mCode->getFunctionArgs(mFunctionOffset);
|
||||
String args = mModule->getFunctionArgs(mFunctionName, mFunctionOffset);
|
||||
if (args.isEmpty())
|
||||
return "()";
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue