mirror of
https://github.com/PCSX2/pcsx2.git
synced 2024-11-23 09:29:42 +00:00
Debugger: Make the expression parser thread safe
This commit is contained in:
parent
8132a8a7f8
commit
efb43ac7f9
@ -80,6 +80,8 @@ void BreakpointDialog::onRdoButtonToggled()
|
||||
|
||||
void BreakpointDialog::accept()
|
||||
{
|
||||
std::string error;
|
||||
|
||||
if (m_purpose == PURPOSE::CREATE)
|
||||
{
|
||||
if (m_ui.rdoExecute->isChecked())
|
||||
@ -93,9 +95,9 @@ void BreakpointDialog::accept()
|
||||
PostfixExpression expr;
|
||||
|
||||
u64 address;
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), address))
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), address, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Address"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -108,9 +110,9 @@ void BreakpointDialog::accept()
|
||||
bp->hasCond = true;
|
||||
bp->cond.debug = m_cpu;
|
||||
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr))
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -121,16 +123,16 @@ void BreakpointDialog::accept()
|
||||
if (auto* mc = std::get_if<MemCheck>(&m_bp_mc))
|
||||
{
|
||||
u64 startAddress;
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), startAddress))
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtAddress->text().toStdString().c_str(), startAddress, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Address"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Address"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
u64 size;
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtSize->text().toStdString().c_str(), size) || !size)
|
||||
if (!m_cpu->evaluateExpression(m_ui.txtSize->text().toStdString().c_str(), size, error) || !size)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Size"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Size"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -143,9 +145,9 @@ void BreakpointDialog::accept()
|
||||
mc->cond.debug = m_cpu;
|
||||
|
||||
PostfixExpression expr;
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr))
|
||||
if (!m_cpu->initExpression(m_ui.txtCondition->text().toStdString().c_str(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Invalid Condition"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -170,9 +170,10 @@ void DisassemblyWidget::contextGoToAddress()
|
||||
return;
|
||||
|
||||
u64 address = 0;
|
||||
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address))
|
||||
std::string error;
|
||||
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -599,9 +599,10 @@ void MemoryViewWidget::contextGoToAddress()
|
||||
return;
|
||||
|
||||
u64 address = 0;
|
||||
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address))
|
||||
std::string error;
|
||||
if (!m_cpu->evaluateExpression(targetString.toStdString().c_str(), address, error))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), getExpressionError());
|
||||
QMessageBox::warning(this, tr("Cannot Go To"), QString::fromStdString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -273,6 +273,8 @@ Qt::ItemFlags BreakpointModel::flags(const QModelIndex& index) const
|
||||
|
||||
bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
if (role == Qt::CheckStateRole && index.column() == BreakpointColumns::ENABLED)
|
||||
{
|
||||
auto bp_mc = m_breakpoints.at(index.row());
|
||||
@ -314,9 +316,9 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
|
||||
{
|
||||
PostfixExpression expr;
|
||||
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr))
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString(getExpressionError()));
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -347,9 +349,9 @@ bool BreakpointModel::setData(const QModelIndex& index, const QVariant& value, i
|
||||
{
|
||||
PostfixExpression expr;
|
||||
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr))
|
||||
if (!m_cpu.initExpression(condValue.toLocal8Bit().constData(), expr, error))
|
||||
{
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString(getExpressionError()));
|
||||
QMessageBox::warning(nullptr, "Condition Error", QString::fromStdString(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -456,17 +458,20 @@ void BreakpointModel::refreshData()
|
||||
|
||||
void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
bool ok;
|
||||
if (fields.size() != BreakpointModel::BreakpointColumns::COLUMN_COUNT)
|
||||
if (fields.size() != BreakpointColumns::COLUMN_COUNT)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Invalid number of columns, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
const int type = fields[BreakpointModel::BreakpointColumns::TYPE].toUInt(&ok);
|
||||
const int type = fields[BreakpointColumns::TYPE].toUInt(&ok);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse type '%s', skipping", fields[BreakpointModel::BreakpointColumns::TYPE].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse type '%s', skipping",
|
||||
fields[BreakpointColumns::TYPE].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -476,34 +481,37 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
|
||||
BreakPoint bp;
|
||||
|
||||
// Address
|
||||
bp.addr = fields[BreakpointModel::BreakpointColumns::OFFSET].toUInt(&ok, 16);
|
||||
bp.addr = fields[BreakpointColumns::OFFSET].toUInt(&ok, 16);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", fields[BreakpointModel::BreakpointColumns::OFFSET].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping",
|
||||
fields[BreakpointColumns::OFFSET].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
// Condition
|
||||
if (!fields[BreakpointModel::BreakpointColumns::CONDITION].isEmpty())
|
||||
if (!fields[BreakpointColumns::CONDITION].isEmpty())
|
||||
{
|
||||
PostfixExpression expr;
|
||||
bp.hasCond = true;
|
||||
bp.cond.debug = &m_cpu;
|
||||
|
||||
if (!m_cpu.initExpression(fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData(), expr))
|
||||
if (!m_cpu.initExpression(fields[BreakpointColumns::CONDITION].toUtf8().constData(), expr, error))
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping",
|
||||
fields[BreakpointModel::CONDITION].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
bp.cond.expression = expr;
|
||||
bp.cond.expressionString = fields[BreakpointModel::BreakpointColumns::CONDITION].toStdString();
|
||||
bp.cond.expressionString = fields[BreakpointColumns::CONDITION].toStdString();
|
||||
}
|
||||
|
||||
// Enabled
|
||||
bp.enabled = fields[BreakpointModel::BreakpointColumns::ENABLED].toUInt(&ok);
|
||||
bp.enabled = fields[BreakpointColumns::ENABLED].toUInt(&ok);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse enable flag '%s', skipping", fields[BreakpointModel::BreakpointColumns::ENABLED].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse enable flag '%s', skipping",
|
||||
fields[BreakpointColumns::ENABLED].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -515,49 +523,54 @@ void BreakpointModel::loadBreakpointFromFieldList(QStringList fields)
|
||||
// Mode
|
||||
if (type >= MEMCHECK_INVALID)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond type '%s', skipping", fields[BreakpointModel::BreakpointColumns::TYPE].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond type '%s', skipping",
|
||||
fields[BreakpointColumns::TYPE].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
mc.memCond = static_cast<MemCheckCondition>(type);
|
||||
|
||||
// Address
|
||||
QString test = fields[BreakpointModel::BreakpointColumns::OFFSET];
|
||||
mc.start = fields[BreakpointModel::BreakpointColumns::OFFSET].toUInt(&ok, 16);
|
||||
QString test = fields[BreakpointColumns::OFFSET];
|
||||
mc.start = fields[BreakpointColumns::OFFSET].toUInt(&ok, 16);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping", fields[BreakpointModel::BreakpointColumns::OFFSET].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse address '%s', skipping",
|
||||
fields[BreakpointColumns::OFFSET].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
// Size
|
||||
mc.end = fields[BreakpointModel::BreakpointColumns::SIZE_LABEL].toUInt(&ok) + mc.start;
|
||||
mc.end = fields[BreakpointColumns::SIZE_LABEL].toUInt(&ok) + mc.start;
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse length '%s', skipping", fields[BreakpointModel::BreakpointColumns::SIZE_LABEL].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse length '%s', skipping",
|
||||
fields[BreakpointColumns::SIZE_LABEL].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
|
||||
// Condition
|
||||
if (!fields[BreakpointModel::BreakpointColumns::CONDITION].isEmpty())
|
||||
if (!fields[BreakpointColumns::CONDITION].isEmpty())
|
||||
{
|
||||
PostfixExpression expr;
|
||||
mc.hasCond = true;
|
||||
mc.cond.debug = &m_cpu;
|
||||
|
||||
if (!m_cpu.initExpression(fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData(), expr))
|
||||
if (!m_cpu.initExpression(fields[BreakpointColumns::CONDITION].toUtf8().constData(), expr, error))
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping", fields[BreakpointModel::BreakpointColumns::CONDITION].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse cond '%s', skipping",
|
||||
fields[BreakpointColumns::CONDITION].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
mc.cond.expression = expr;
|
||||
mc.cond.expressionString = fields[BreakpointModel::BreakpointColumns::CONDITION].toStdString();
|
||||
mc.cond.expressionString = fields[BreakpointColumns::CONDITION].toStdString();
|
||||
}
|
||||
|
||||
// Result
|
||||
const int result = fields[BreakpointModel::BreakpointColumns::ENABLED].toUInt(&ok);
|
||||
const int result = fields[BreakpointColumns::ENABLED].toUInt(&ok);
|
||||
if (!ok)
|
||||
{
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse result flag '%s', skipping", fields[BreakpointModel::BreakpointColumns::ENABLED].toUtf8().constData());
|
||||
Console.WriteLn("Debugger Breakpoint Model: Failed to parse result flag '%s', skipping",
|
||||
fields[BreakpointColumns::ENABLED].toUtf8().constData());
|
||||
return;
|
||||
}
|
||||
mc.result = static_cast<MemCheckResult>(result);
|
||||
|
@ -24,7 +24,8 @@ struct BreakPointCond
|
||||
u32 Evaluate()
|
||||
{
|
||||
u64 result;
|
||||
if (!debug->parseExpression(expression, result) || result == 0)
|
||||
std::string error;
|
||||
if (!debug->parseExpression(expression, result, error) || result == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ std::optional<u32> DebugInterface::getStackFrameSize(const ccc::Function& functi
|
||||
// The stack frame size isn't stored in the symbol table, so we try
|
||||
// to extract it from the code by checking for an instruction at the
|
||||
// start of the current function that is in the form of
|
||||
// "addui $sp, $sp, frame_size" instead.
|
||||
// "addiu $sp, $sp, frame_size" instead.
|
||||
|
||||
u32 instruction = read32(function.address().value);
|
||||
|
||||
@ -354,29 +354,29 @@ std::optional<u32> DebugInterface::getStackFrameSize(const ccc::Function& functi
|
||||
return static_cast<u32>(stack_frame_size);
|
||||
}
|
||||
|
||||
bool DebugInterface::evaluateExpression(const char* expression, u64& dest)
|
||||
bool DebugInterface::evaluateExpression(const char* expression, u64& dest, std::string& error)
|
||||
{
|
||||
PostfixExpression postfix;
|
||||
|
||||
if (!initExpression(expression, postfix))
|
||||
if (!initExpression(expression, postfix, error))
|
||||
return false;
|
||||
|
||||
if (!parseExpression(postfix, dest))
|
||||
if (!parseExpression(postfix, dest, error))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DebugInterface::initExpression(const char* exp, PostfixExpression& dest)
|
||||
bool DebugInterface::initExpression(const char* exp, PostfixExpression& dest, std::string& error)
|
||||
{
|
||||
MipsExpressionFunctions funcs(this, true);
|
||||
return initPostfixExpression(exp, &funcs, dest);
|
||||
return initPostfixExpression(exp, &funcs, dest, error);
|
||||
}
|
||||
|
||||
bool DebugInterface::parseExpression(PostfixExpression& exp, u64& dest)
|
||||
bool DebugInterface::parseExpression(PostfixExpression& exp, u64& dest, std::string& error)
|
||||
{
|
||||
MipsExpressionFunctions funcs(this, false);
|
||||
return parsePostfixExpression(exp, &funcs, dest);
|
||||
return parsePostfixExpression(exp, &funcs, dest, error);
|
||||
}
|
||||
|
||||
//
|
||||
@ -904,12 +904,10 @@ std::vector<std::unique_ptr<BiosThread>> R5900DebugInterface::GetThreadList() co
|
||||
return getEEThreads();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// R3000DebugInterface
|
||||
//
|
||||
|
||||
|
||||
BreakPointCpu R3000DebugInterface::getCpuType()
|
||||
{
|
||||
return BREAKPOINT_IOP;
|
||||
|
@ -86,9 +86,9 @@ public:
|
||||
virtual SymbolImporter* GetSymbolImporter() const = 0;
|
||||
virtual std::vector<std::unique_ptr<BiosThread>> GetThreadList() const = 0;
|
||||
|
||||
bool evaluateExpression(const char* expression, u64& dest);
|
||||
bool initExpression(const char* exp, PostfixExpression& dest);
|
||||
bool parseExpression(PostfixExpression& exp, u64& dest);
|
||||
bool evaluateExpression(const char* expression, u64& dest, std::string& error);
|
||||
bool initExpression(const char* exp, PostfixExpression& dest, std::string& error);
|
||||
bool parseExpression(PostfixExpression& exp, u64& dest, std::string& error);
|
||||
bool isAlive();
|
||||
bool isCpuPaused();
|
||||
void pauseCpu();
|
||||
|
@ -21,8 +21,6 @@ typedef enum {
|
||||
|
||||
typedef enum { EXCOMM_CONST, EXCOMM_CONST_FLOAT, EXCOMM_REF, EXCOMM_OP } ExpressionCommand;
|
||||
|
||||
static std::string expressionError;
|
||||
|
||||
typedef struct {
|
||||
char Name[4];
|
||||
unsigned char Priority;
|
||||
@ -209,10 +207,8 @@ bool isAlphaNum(char c)
|
||||
c == '@' || c == '_' || c == '$' || c == '.');
|
||||
}
|
||||
|
||||
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest)
|
||||
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest, std::string& error)
|
||||
{
|
||||
expressionError.clear();
|
||||
|
||||
int infixPos = 0;
|
||||
int infixLen = (int)strlen(infix);
|
||||
ExpressionOpcodeType lastOpcode = EXOP_NONE;
|
||||
@ -241,7 +237,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
|
||||
if(subPos == sizeof(subStr) - 1)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Token too long.");
|
||||
error = TRANSLATE("ExpressionParser", "Token too long.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -251,7 +247,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
isFloat = true;
|
||||
else if (!parseNumber(subStr,16,subPos,value))
|
||||
{
|
||||
expressionError = StringUtil::StdStringFromFormat(
|
||||
error = StringUtil::StdStringFromFormat(
|
||||
TRANSLATE("ExpressionParser", "Invalid number \"%s\"."), subStr);
|
||||
return false;
|
||||
}
|
||||
@ -268,7 +264,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
|
||||
if(subPos == sizeof(subStr) - 1)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Token too long.");
|
||||
error = TRANSLATE("ExpressionParser", "Token too long.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -294,7 +290,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
continue;
|
||||
}
|
||||
|
||||
expressionError = StringUtil::StdStringFromFormat(
|
||||
error = StringUtil::StdStringFromFormat(
|
||||
TRANSLATE("ExpressionParser", "Invalid symbol \"%s\"."), subStr);
|
||||
return false;
|
||||
} else {
|
||||
@ -302,7 +298,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
ExpressionOpcodeType type = getExpressionOpcode(&infix[infixPos],len,lastOpcode);
|
||||
if (type == EXOP_NONE)
|
||||
{
|
||||
expressionError = StringUtil::StdStringFromFormat(
|
||||
error = StringUtil::StdStringFromFormat(
|
||||
TRANSLATE("ExpressionParser", "Invalid operator at \"%s\"."), &infix[infixPos]);
|
||||
return false;
|
||||
}
|
||||
@ -318,7 +314,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
{
|
||||
if (opcodeStack.empty())
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Closing parenthesis without opening one.");
|
||||
error = TRANSLATE("ExpressionParser", "Closing parenthesis without opening one.");
|
||||
return false;
|
||||
}
|
||||
ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1];
|
||||
@ -332,7 +328,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
{
|
||||
if (opcodeStack.empty())
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Closing bracket without opening one.");
|
||||
error = TRANSLATE("ExpressionParser", "Closing bracket without opening one.");
|
||||
return false;
|
||||
}
|
||||
ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1];
|
||||
@ -385,7 +381,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
|
||||
if (t == EXOP_BRACKETL) // opening bracket without closing one
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Parenthesis not closed.");
|
||||
error = TRANSLATE("ExpressionParser", "Parenthesis not closed.");
|
||||
return false;
|
||||
}
|
||||
dest.push_back(ExpressionPair(EXCOMM_OP,t));
|
||||
@ -415,7 +411,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest)
|
||||
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest, std::string& error)
|
||||
{
|
||||
size_t num = 0;
|
||||
u64 opcode;
|
||||
@ -444,7 +440,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
opcode = exp[num++].second;
|
||||
if (valueStack.size() < ExpressionOpcodes[opcode].args)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Not enough arguments.");
|
||||
error = TRANSLATE("ExpressionParser", "Not enough arguments.");
|
||||
return false;
|
||||
}
|
||||
for (int l = 0; l < ExpressionOpcodes[opcode].args; l++)
|
||||
@ -459,12 +455,12 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_MEMSIZE: // must be followed by EXOP_MEM
|
||||
if (exp[num++].second != EXOP_MEM)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Invalid memsize operator.");
|
||||
error = TRANSLATE("ExpressionParser", "Invalid memsize operator.");
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 val;
|
||||
if(!funcs->getMemoryValue(arg[1],arg[0],val,expressionError))
|
||||
if(!funcs->getMemoryValue(arg[1],arg[0],val,error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -473,7 +469,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_MEM:
|
||||
{
|
||||
u64 val;
|
||||
if (!funcs->getMemoryValue(arg[0],4,val,expressionError))
|
||||
if (!funcs->getMemoryValue(arg[0],4,val,error))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -503,7 +499,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_DIV: // a/b
|
||||
if (arg[0] == 0)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Division by zero.");
|
||||
error = TRANSLATE("ExpressionParser", "Division by zero.");
|
||||
return false;
|
||||
}
|
||||
if (useFloat)
|
||||
@ -514,7 +510,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_MOD: // a%b
|
||||
if (arg[0] == 0)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Modulo by zero.");
|
||||
error = TRANSLATE("ExpressionParser", "Modulo by zero.");
|
||||
return false;
|
||||
}
|
||||
valueStack.push_back(arg[1]%arg[0]);
|
||||
@ -593,7 +589,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
case EXOP_TERTELSE: // exp ? exp : exp, else muss zuerst kommen!
|
||||
if (exp[num++].second != EXOP_TERTIF)
|
||||
{
|
||||
expressionError = TRANSLATE("ExpressionParser", "Invalid tertiary operator.");
|
||||
error = TRANSLATE("ExpressionParser", "Invalid tertiary operator.");
|
||||
return false;
|
||||
}
|
||||
valueStack.push_back(arg[2]?arg[1]:arg[0]);
|
||||
@ -608,17 +604,9 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseExpression(char* exp, IExpressionFunctions* funcs, u64& dest)
|
||||
bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest, std::string& error)
|
||||
{
|
||||
PostfixExpression postfix;
|
||||
if (!initPostfixExpression(exp,funcs,postfix)) return false;
|
||||
return parsePostfixExpression(postfix,funcs,dest);
|
||||
}
|
||||
|
||||
const char* getExpressionError()
|
||||
{
|
||||
if (expressionError.empty())
|
||||
return TRANSLATE("ExpressionParser", "Invalid expression.");
|
||||
|
||||
return expressionError.c_str();
|
||||
if (!initPostfixExpression(exp,funcs,postfix,error)) return false;
|
||||
return parsePostfixExpression(postfix,funcs,dest,error);
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ public:
|
||||
virtual bool getMemoryValue(u32 address, int size, u64& dest, std::string& error) = 0;
|
||||
};
|
||||
|
||||
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest);
|
||||
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest);
|
||||
bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest);
|
||||
const char* getExpressionError();
|
||||
bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, PostfixExpression& dest, std::string& error);
|
||||
bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, u64& dest, std::string& error);
|
||||
bool parseExpression(const char* exp, IExpressionFunctions* funcs, u64& dest, std::string& error);
|
||||
|
@ -355,11 +355,12 @@ bool MipsCheckImmediate(const char* Source, DebugInterface* cpu, int& dest, int&
|
||||
RetLen = SourceLen;
|
||||
|
||||
PostfixExpression postfix;
|
||||
if (!cpu->initExpression(Buffer,postfix))
|
||||
std::string error;
|
||||
if (!cpu->initExpression(Buffer,postfix,error))
|
||||
return false;
|
||||
|
||||
u64 value;
|
||||
if (!cpu->parseExpression(postfix,value))
|
||||
if (!cpu->parseExpression(postfix,value,error))
|
||||
return false;
|
||||
|
||||
dest = (int) value;
|
||||
|
Loading…
Reference in New Issue
Block a user