debugger support

This commit is contained in:
Jeff Hutchinson 2021-08-19 22:05:43 -04:00
parent 98a2fa0f33
commit 59312d7d52
8 changed files with 46 additions and 15 deletions

View file

@ -1599,7 +1599,7 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
CompilerLocalVariableToRegisterMappingTable* tbl = &getFunctionVariableMappingTable(); CompilerLocalVariableToRegisterMappingTable* tbl = &getFunctionVariableMappingTable();
for (const auto& pair : gFuncVars->variableNameMap) for (const auto& pair : gFuncVars->variableNameMap)
{ {
tbl->add(fnName, pair.second, pair.first); tbl->add(fnName, nameSpace, pair.second, pair.first);
} }
gFuncVars = NULL; gFuncVars = NULL;

View file

@ -35,8 +35,8 @@ struct CompilerLocalVariableToRegisterMappingTable
std::unordered_map<StringTableEntry, RemappingTable> localVarToRegister; std::unordered_map<StringTableEntry, RemappingTable> localVarToRegister;
void add(StringTableEntry functionName, StringTableEntry varName, S32 reg); void add(StringTableEntry functionName, StringTableEntry namespaceName, StringTableEntry varName, S32 reg);
S32 lookup(StringTableEntry functionName, StringTableEntry varName); S32 lookup(StringTableEntry namespaceName, StringTableEntry functionName, StringTableEntry varName);
CompilerLocalVariableToRegisterMappingTable copy(); CompilerLocalVariableToRegisterMappingTable copy();
void reset(); void reset();
}; };

View file

@ -212,17 +212,21 @@ void CompilerStringTable::write(Stream &st)
//------------------------------------------------------------ //------------------------------------------------------------
void CompilerLocalVariableToRegisterMappingTable::add(StringTableEntry functionName, StringTableEntry varName, S32 reg) void CompilerLocalVariableToRegisterMappingTable::add(StringTableEntry functionName, StringTableEntry namespaceName, StringTableEntry varName, S32 reg)
{ {
localVarToRegister[functionName].table[varName] = reg; StringTableEntry funcLookupTableName = StringTable->insert(avar("%s::%s", namespaceName, functionName));
localVarToRegister[funcLookupTableName].table[varName] = reg;
} }
S32 CompilerLocalVariableToRegisterMappingTable::lookup(StringTableEntry functionName, StringTableEntry varName) S32 CompilerLocalVariableToRegisterMappingTable::lookup(StringTableEntry namespaceName, StringTableEntry functionName, StringTableEntry varName)
{ {
auto functionPosition = localVarToRegister.find(functionName); StringTableEntry funcLookupTableName = StringTable->insert(avar("%s::%s", namespaceName, functionName));
auto functionPosition = localVarToRegister.find(funcLookupTableName);
if (functionPosition != localVarToRegister.end()) if (functionPosition != localVarToRegister.end())
{ {
const auto& table = localVarToRegister[functionName].table; const auto& table = localVarToRegister[funcLookupTableName].table;
auto varPosition = table.find(varName); auto varPosition = table.find(varName);
if (varPosition != table.end()) if (varPosition != table.end())
{ {
@ -230,7 +234,7 @@ S32 CompilerLocalVariableToRegisterMappingTable::lookup(StringTableEntry functio
} }
} }
Con::errorf("Unable to find local variable %s in function name %s", varName, functionName); Con::errorf("Unable to find local variable %s in function name %s", varName, funcLookupTableName);
return -1; return -1;
} }

View file

@ -1923,7 +1923,7 @@ void postConsoleInput( RawData data )
{ {
// TODO(JTH): Mem leak // TODO(JTH): Mem leak
// Schedule this to happen at the next time event. // Schedule this to happen at the next time event.
ConsoleValue* argv = new ConsoleValue[2]; ConsoleValue* argv = new ConsoleValue[2]();
argv[0].setString("eval"); argv[0].setString("eval");
argv[1].setString(reinterpret_cast<const char*>(data.data)); argv[1].setString(reinterpret_cast<const char*>(data.data));
@ -2563,7 +2563,7 @@ ConsoleValueToStringArrayWrapper::~ConsoleValueToStringArrayWrapper()
StringArrayToConsoleValueWrapper::StringArrayToConsoleValueWrapper(int targc, const char** targv) StringArrayToConsoleValueWrapper::StringArrayToConsoleValueWrapper(int targc, const char** targv)
{ {
argv = new ConsoleValue[targc]; argv = new ConsoleValue[targc]();
argc = targc; argc = targc;
for (int i=0; i<targc; i++) for (int i=0; i<targc; i++)

View file

@ -710,7 +710,7 @@ void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns, S32 reg
AssertFatal(!newFrame.getCount(), "ExprEvalState::pushFrame - Dictionary not empty!"); AssertFatal(!newFrame.getCount(), "ExprEvalState::pushFrame - Dictionary not empty!");
ConsoleValue* consoleValArray = new ConsoleValue[registerCount]; ConsoleValue* consoleValArray = new ConsoleValue[registerCount]();
localStack.push_back(ConsoleValueFrame(consoleValArray, false)); localStack.push_back(ConsoleValueFrame(consoleValArray, false));
currentRegisterArray = &localStack.last(); currentRegisterArray = &localStack.last();
@ -787,6 +787,19 @@ void ExprEvalState::pushFrameRef(S32 stackIndex)
#endif #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() ExprEvalState::ExprEvalState()
{ {
VECTOR_SET_ASSOCIATION(stack); VECTOR_SET_ASSOCIATION(stack);

View file

@ -634,6 +634,8 @@ public:
/// on the top of the stack. /// on the top of the stack.
void pushFrameRef(S32 stackIndex); void pushFrameRef(S32 stackIndex);
void pushDebugFrame(S32 stackIndex);
U32 getStackDepth() const U32 getStackDepth() const
{ {
return mStackDepth; return mStackDepth;

View file

@ -33,7 +33,7 @@ SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValue *argv, bool onObject)
mOnObject = onObject; mOnObject = onObject;
mArgc = argc; mArgc = argc;
mArgv = new ConsoleValue[argc]; mArgv = new ConsoleValue[argc]();
for (int i=0; i<argc; i++) for (int i=0; i<argc; i++)
{ {
if (argv) if (argv)

View file

@ -870,11 +870,21 @@ void TelnetDebugger::evaluateExpression(const char *tag, S32 frame, const char *
bool isEvaluatingLocalVariable = evalBufferLen > 0 && evalBuffer[0] == '%'; bool isEvaluatingLocalVariable = evalBufferLen > 0 && evalBuffer[0] == '%';
if (isEvaluatingLocalVariable) if (isEvaluatingLocalVariable)
{ {
// See calculation of current frame in pushing a reference frame for console exec, we need access
// to the proper scope.
//frame = gEvalState.getTopOfStack() - frame - 1;
S32 stackIndex = gEvalState.getTopOfStack() - frame - 1;
const char* format = "EVALOUT %s %s\r\n"; const char* format = "EVALOUT %s %s\r\n";
Dictionary &stackFrame = gEvalState.getFrameAt(frame); gEvalState.pushDebugFrame(stackIndex);
Dictionary& stackFrame = gEvalState.getCurrentFrame();
StringTableEntry functionName = stackFrame.scopeName; StringTableEntry functionName = stackFrame.scopeName;
S32 registerId = stackFrame.code->variableRegisterTable.lookup(functionName, StringTable->insert(evalBuffer)); StringTableEntry namespaceName = stackFrame.scopeNamespace->mName;
StringTableEntry varToLookup = StringTable->insert(evalBuffer);
S32 registerId = stackFrame.code->variableRegisterTable.lookup(namespaceName, functionName, varToLookup);
if (registerId == -1) if (registerId == -1)
{ {
@ -885,6 +895,8 @@ void TelnetDebugger::evaluateExpression(const char *tag, S32 frame, const char *
const char* varResult = gEvalState.getLocalStringVariable(registerId); const char* varResult = gEvalState.getLocalStringVariable(registerId);
gEvalState.popFrame();
S32 len = dStrlen(format) + dStrlen(tag) + dStrlen(varResult); S32 len = dStrlen(format) + dStrlen(tag) + dStrlen(varResult);
char* buffer = new char[len]; char* buffer = new char[len];
dSprintf(buffer, len, format, tag, varResult[0] ? varResult : "\"\""); dSprintf(buffer, len, format, tag, varResult[0] ? varResult : "\"\"");