mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
hacks to make thedebugger work again.
This commit is contained in:
parent
717c7acca9
commit
a449fadde2
|
|
@ -62,6 +62,7 @@ class FuncVars
|
|||
{
|
||||
S32 reg;
|
||||
TypeReq currentType;
|
||||
StringTableEntry name;
|
||||
bool isConstant;
|
||||
};
|
||||
|
||||
|
|
@ -76,7 +77,9 @@ public:
|
|||
}
|
||||
|
||||
S32 id = counter++;
|
||||
vars[var] = { id, currentType, isConstant };
|
||||
vars[var] = { id, currentType, var, isConstant };
|
||||
variableNameMap[id] = var;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
@ -97,6 +100,8 @@ public:
|
|||
|
||||
inline S32 count() { return counter; }
|
||||
|
||||
std::unordered_map<S32, StringTableEntry> variableNameMap;
|
||||
|
||||
private:
|
||||
std::unordered_map<StringTableEntry, Var> vars;
|
||||
S32 counter = 0;
|
||||
|
|
@ -1604,6 +1609,14 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
|
|||
|
||||
setCurrentStringTable(&getGlobalStringTable());
|
||||
setCurrentFloatTable(&getGlobalFloatTable());
|
||||
|
||||
// map local variables to registers for this function.
|
||||
CompilerLocalVariableToRegisterMappingTable* tbl = &getFunctionVariableMappingTable();
|
||||
for (const auto& pair : gFuncVars->variableNameMap)
|
||||
{
|
||||
tbl->add(fnName, pair.second, pair.first);
|
||||
}
|
||||
|
||||
gFuncVars = NULL;
|
||||
|
||||
return ip;
|
||||
|
|
|
|||
|
|
@ -640,6 +640,8 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr
|
|||
globalFloats = getGlobalFloatTable().build();
|
||||
functionFloats = getFunctionFloatTable().build();
|
||||
|
||||
variableRegisterTable = getFunctionVariableMappingTable().copy();
|
||||
|
||||
codeStream.emit(OP_RETURN_VOID);
|
||||
codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,24 @@
|
|||
#ifndef _CODEBLOCK_H_
|
||||
#define _CODEBLOCK_H_
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
struct CompilerLocalVariableToRegisterMappingTable
|
||||
{
|
||||
// First key: function name
|
||||
struct RemappingTable
|
||||
{
|
||||
std::unordered_map<StringTableEntry, S32> table;
|
||||
};
|
||||
|
||||
std::unordered_map<StringTableEntry, RemappingTable> localVarToRegister;
|
||||
|
||||
void add(StringTableEntry functionName, StringTableEntry varName, S32 reg);
|
||||
S32 lookup(StringTableEntry functionName, StringTableEntry varName);
|
||||
CompilerLocalVariableToRegisterMappingTable copy();
|
||||
void reset();
|
||||
};
|
||||
|
||||
#include "console/compiler.h"
|
||||
#include "console/consoleParser.h"
|
||||
|
||||
|
|
@ -34,7 +52,6 @@ class ConsoleValue;
|
|||
/// This class represents a block of code, usually mapped directly to a file.
|
||||
class CodeBlock
|
||||
{
|
||||
friend class CodeInterpreter;
|
||||
private:
|
||||
static CodeBlock* smCodeBlockList;
|
||||
static CodeBlock* smCurrentCodeBlock;
|
||||
|
|
@ -77,6 +94,8 @@ public:
|
|||
U32 codeSize;
|
||||
U32 *code;
|
||||
|
||||
CompilerLocalVariableToRegisterMappingTable variableRegisterTable;
|
||||
|
||||
U32 refCount;
|
||||
U32 lineBreakPairCount;
|
||||
U32 *lineBreakPairs;
|
||||
|
|
|
|||
|
|
@ -1773,8 +1773,8 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
//if this is called from inside a function, append the ip and codeptr
|
||||
if (!gEvalState.stack.empty())
|
||||
{
|
||||
gEvalState.stack.last()->code = this;
|
||||
gEvalState.stack.last()->ip = ip - 1;
|
||||
gEvalState.getCurrentFrame().code = this;
|
||||
gEvalState.getCurrentFrame().ip = ip - 1;
|
||||
}
|
||||
|
||||
ip += 5;
|
||||
|
|
@ -2070,8 +2070,8 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
{
|
||||
//append the ip and codeptr before managing the breakpoint!
|
||||
AssertFatal(!gEvalState.stack.empty(), "Empty eval stack on break!");
|
||||
gEvalState.stack.last()->code = this;
|
||||
gEvalState.stack.last()->ip = ip - 1;
|
||||
gEvalState.getCurrentFrame().code = this;
|
||||
gEvalState.getCurrentFrame().ip = ip - 1;
|
||||
|
||||
U32 breakLine;
|
||||
findBreakLine(ip - 1, breakLine, instruction);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ namespace Compiler
|
|||
CompilerFloatTable *gCurrentFloatTable, gGlobalFloatTable, gFunctionFloatTable;
|
||||
DataChunker gConsoleAllocator;
|
||||
CompilerIdentTable gIdentTable;
|
||||
CompilerLocalVariableToRegisterMappingTable gFunctionVariableMappingTable;
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
|
|
@ -92,6 +93,8 @@ namespace Compiler
|
|||
CompilerStringTable &getGlobalStringTable() { return gGlobalStringTable; }
|
||||
CompilerStringTable &getFunctionStringTable() { return gFunctionStringTable; }
|
||||
|
||||
CompilerLocalVariableToRegisterMappingTable& getFunctionVariableMappingTable() { return gFunctionVariableMappingTable; }
|
||||
|
||||
void setCurrentStringTable(CompilerStringTable* cst) { gCurrentStringTable = cst; }
|
||||
|
||||
CompilerFloatTable *getCurrentFloatTable() { return gCurrentFloatTable; }
|
||||
|
|
@ -117,6 +120,7 @@ namespace Compiler
|
|||
getFunctionFloatTable().reset();
|
||||
getFunctionStringTable().reset();
|
||||
getIdentTable().reset();
|
||||
getFunctionVariableMappingTable().reset();
|
||||
}
|
||||
|
||||
void *consoleAlloc(U32 size) { return gConsoleAllocator.alloc(size); }
|
||||
|
|
@ -208,6 +212,43 @@ void CompilerStringTable::write(Stream &st)
|
|||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void CompilerLocalVariableToRegisterMappingTable::add(StringTableEntry functionName, StringTableEntry varName, S32 reg)
|
||||
{
|
||||
localVarToRegister[functionName].table[varName] = reg;
|
||||
}
|
||||
|
||||
S32 CompilerLocalVariableToRegisterMappingTable::lookup(StringTableEntry functionName, StringTableEntry varName)
|
||||
{
|
||||
auto functionPosition = localVarToRegister.find(functionName);
|
||||
if (functionPosition != localVarToRegister.end())
|
||||
{
|
||||
const auto& table = localVarToRegister[functionName].table;
|
||||
auto varPosition = table.find(varName);
|
||||
if (varPosition != table.end())
|
||||
{
|
||||
return varPosition->second;
|
||||
}
|
||||
}
|
||||
|
||||
Con::errorf("Unable to find local variable %s in function name %s", varName, functionName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CompilerLocalVariableToRegisterMappingTable CompilerLocalVariableToRegisterMappingTable::copy()
|
||||
{
|
||||
// Trivilly copyable as its all plain old data and using STL containers... (We want a deep copy though!)
|
||||
CompilerLocalVariableToRegisterMappingTable table;
|
||||
table.localVarToRegister = localVarToRegister;
|
||||
return std::move(table);
|
||||
}
|
||||
|
||||
void CompilerLocalVariableToRegisterMappingTable::reset()
|
||||
{
|
||||
localVarToRegister.clear();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
U32 CompilerFloatTable::add(F64 value)
|
||||
{
|
||||
Entry **walk;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ class DataChunker;
|
|||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
/// The opcodes for the TorqueScript VM.
|
||||
|
|
@ -252,6 +254,7 @@ namespace Compiler
|
|||
CompilerStringTable *getCurrentStringTable();
|
||||
CompilerStringTable &getGlobalStringTable();
|
||||
CompilerStringTable &getFunctionStringTable();
|
||||
CompilerLocalVariableToRegisterMappingTable& getFunctionVariableMappingTable();
|
||||
|
||||
void setCurrentStringTable(CompilerStringTable* cst);
|
||||
|
||||
|
|
|
|||
|
|
@ -644,6 +644,11 @@ public:
|
|||
return *(stack[mStackDepth - 1]);
|
||||
}
|
||||
|
||||
Dictionary& getFrameAt(S32 depth)
|
||||
{
|
||||
return *(stack[depth]);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// Run integrity checks for debugging.
|
||||
|
|
|
|||
|
|
@ -864,6 +864,37 @@ void TelnetDebugger::evaluateExpression(const char *tag, S32 frame, const char *
|
|||
if ( frame < 0 )
|
||||
frame = 0;
|
||||
|
||||
// Local variables use their own memory management and can't be queried by just executing
|
||||
// TorqueScript, we have to go digging into the interpreter.
|
||||
S32 evalBufferLen = dStrlen(evalBuffer);
|
||||
bool isEvaluatingLocalVariable = evalBufferLen > 0 && evalBuffer[0] == '%';
|
||||
if (isEvaluatingLocalVariable)
|
||||
{
|
||||
const char* format = "EVALOUT %s %s\r\n";
|
||||
|
||||
Dictionary &stackFrame = gEvalState.getFrameAt(frame);
|
||||
StringTableEntry functionName = stackFrame.scopeName;
|
||||
S32 registerId = stackFrame.code->variableRegisterTable.lookup(functionName, StringTable->insert(evalBuffer));
|
||||
|
||||
if (registerId == -1)
|
||||
{
|
||||
// ERROR, can't read the variable!
|
||||
send("EVALOUT \"\" \"\"");
|
||||
return;
|
||||
}
|
||||
|
||||
const char* varResult = gEvalState.getLocalStringVariable(registerId);
|
||||
|
||||
S32 len = dStrlen(format) + dStrlen(tag) + dStrlen(varResult);
|
||||
char* buffer = new char[len];
|
||||
dSprintf(buffer, len, format, tag, varResult[0] ? varResult : "\"\"");
|
||||
|
||||
send(buffer);
|
||||
delete[] buffer;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Build a buffer just big enough for this eval.
|
||||
const char* format = "return %s;";
|
||||
dsize_t len = dStrlen( format ) + dStrlen( evalBuffer );
|
||||
|
|
@ -872,14 +903,14 @@ void TelnetDebugger::evaluateExpression(const char *tag, S32 frame, const char *
|
|||
|
||||
// Execute the eval.
|
||||
CodeBlock *newCodeBlock = new CodeBlock();
|
||||
const char* result = newCodeBlock->compileExec( NULL, buffer, false, frame );
|
||||
ConsoleValue result = newCodeBlock->compileExec( NULL, buffer, false, frame );
|
||||
delete [] buffer;
|
||||
|
||||
// Create a new buffer that fits the result.
|
||||
format = "EVALOUT %s %s\r\n";
|
||||
len = dStrlen( format ) + dStrlen( tag ) + dStrlen( result );
|
||||
len = dStrlen( format ) + dStrlen( tag ) + dStrlen( result.getString() );
|
||||
buffer = new char[ len ];
|
||||
dSprintf( buffer, len, format, tag, result[0] ? result : "\"\"" );
|
||||
dSprintf( buffer, len, format, tag, result.getString()[0] ? result.getString() : "\"\"" );
|
||||
|
||||
send( buffer );
|
||||
delete [] buffer;
|
||||
|
|
|
|||
Loading…
Reference in a new issue