1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 10:22:52 +01:00

Remove breakpoint system from ScriptMachine

This commit is contained in:
Daniel Evans 2016-08-10 22:57:48 +01:00
parent 0a982c1fca
commit 8a985309f9
3 changed files with 1 additions and 178 deletions

View File

@ -27,11 +27,6 @@ bool SCMOpcodes::findOpcode(ScriptFunctionID id, ScriptFunctionMeta** out)
return false;
}
void ScriptMachine::interuptNext()
{
interupt = true;
}
void ScriptMachine::executeThread(SCMThread &t, int msPassed)
{
if( t.wakeCounter > 0 ) {
@ -39,8 +34,6 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed)
}
if( t.wakeCounter > 0 ) return;
bool hasDebugging = !! bpHandler;
while( t.wakeCounter == 0 ) {
auto pc = t.programCounter;
auto opcode = _file->read<SCMOpcode>(pc);
@ -128,22 +121,6 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed)
ScriptArguments sca(&parameters, &t, this);
if( hasDebugging )
{
auto activeBreakpoint = findBreakpoint(t, pc);
if( activeBreakpoint || interupt )
{
interupt = false;
SCMBreakpoint bp;
bp.pc = t.programCounter;
bp.thread = &t;
bp.vm = this;
bp.function = &code;
bp.args = &sca;
bpHandler(bp);
}
}
#if RW_SCRIPT_DEBUG
static auto sDebugThreadName = getenv("OPENRW_DEBUG_THREAD");
if (!sDebugThreadName || strncmp(t.name, sDebugThreadName, 8) == 0)
@ -213,7 +190,7 @@ void ScriptMachine::executeThread(SCMThread &t, int msPassed)
}
ScriptMachine::ScriptMachine(GameState* _state, SCMFile *file, SCMOpcodes *ops)
: _file(file), _ops(ops), state(_state), interupt(false)
: _file(file), _ops(ops), state(_state)
{
auto globals = _file->getGlobalsSize();
globalData.resize(globals);
@ -267,49 +244,3 @@ void ScriptMachine::execute(float dt)
}
}
SCMBreakpointInfo* ScriptMachine::findBreakpoint(SCMThread& t, SCMThread::pc_t pc)
{
for(std::vector<SCMBreakpointInfo>::iterator bp = breakpoints.begin(); bp != breakpoints.end(); ++bp)
{
if( (bp->breakpointFlags & SCMBreakpointInfo::BP_ProgramCounter) == SCMBreakpointInfo::BP_ProgramCounter )
{
if( bp->programCounter != pc )
{
continue;
}
}
if( (bp->breakpointFlags & SCMBreakpointInfo::BP_ThreadName) == SCMBreakpointInfo::BP_ThreadName )
{
if( std::strcmp(bp->threadName, t.name) != 0 )
{
continue;
}
}
return &(*bp);
}
return nullptr;
}
void ScriptMachine::setBreakpointHandler(const ScriptMachine::BreakpointHandler& handler)
{
bpHandler = handler;
}
void ScriptMachine::addBreakpoint(const SCMBreakpointInfo& bpi)
{
breakpoints.push_back(bpi);
}
void ScriptMachine::removeBreakpoint(const SCMBreakpointInfo& bpi)
{
for (size_t i = 0; i < breakpoints.size(); ++i)
{
if (bpi == breakpoints[i])
{
breakpoints.erase(breakpoints.begin() + i);
return;
}
}
}

View File

@ -136,59 +136,6 @@ struct SCMThread
std::array<pc_t, SCM_STACK_DEPTH> calls;
};
#include <cstring>
/**
* Stores information about where breakpoints should be triggered.
*
* breakpointFlags stores the state to be checked against.
*/
struct SCMBreakpointInfo
{
enum /* Breakpoint Flags */ {
BP_ProgramCounter = 1,
BP_ThreadName = 2
};
uint8_t breakpointFlags;
SCMThread::pc_t programCounter;
char threadName[17];
bool operator == (const SCMBreakpointInfo& rhs) const
{
if (breakpointFlags != rhs.breakpointFlags) return false;
if ((breakpointFlags & BP_ProgramCounter) != 0)
{
if (programCounter != rhs.programCounter) return false;
}
if ((breakpointFlags & BP_ThreadName) != 0)
{
if (strncmp(threadName, rhs.threadName, 17) != 0) return false;
}
return true;
}
static SCMBreakpointInfo breakThreadName(char threadName[17])
{
SCMBreakpointInfo i;
i.breakpointFlags = BP_ThreadName;
std::strncpy(i.threadName, threadName, 17);
return i;
}
};
/**
* Information about breakpoints that have been hit
*/
struct SCMBreakpoint
{
SCMThread::pc_t pc;
SCMThread* thread;
ScriptMachine* vm;
ScriptFunctionMeta* function;
ScriptArguments* args;
/** The breakpoint entry that triggered this breakpoint */
SCMBreakpointInfo* info;
};
/**
* Implements the actual fetch-execute mechanism for the game script virtual machine.
*
@ -205,9 +152,6 @@ struct SCMBreakpoint
* Within ScriptMachine, each thread's program counter is used to execute an instruction
* by consuming the correct number of arguments, allowing the next instruction to be found,
* and then dispatching a call to the opcode's function.
*
* Breakpoints can be set which will call the breakpoint hander, where it is possible
* to halt execution by refusing to return until the handler is ready to continue.
*/
class ScriptMachine
{
@ -228,32 +172,6 @@ public:
GameState* getState() const { return state; }
typedef std::function<void (const SCMBreakpoint&)> BreakpointHandler;
/**
* Set the breakpoint handler callback.
*
* When the VM reaches an instruction marked as a brekapoint
* by addBreakpoint, the handler will be called with information
* about the state of the VM and the active thread.
*/
void setBreakpointHandler(const BreakpointHandler& handler);
/**
* Adds a breakpoint
*/
void addBreakpoint(const SCMBreakpointInfo& bpi);
/**
* Removes a breakpoint.
*/
void removeBreakpoint(const SCMBreakpointInfo& bpi);
/**
* Interupt VM execution at the start of the next instruction
*/
void interuptNext();
/**
* @brief executes threads until they are all in waiting state.
*/
@ -263,18 +181,12 @@ private:
SCMFile* _file;
SCMOpcodes* _ops;
GameState* state;
bool interupt;
std::list<SCMThread> _activeThreads;
void executeThread(SCMThread& t, int msPassed);
SCMBreakpointInfo* findBreakpoint(SCMThread& t, SCMThread::pc_t pc);
std::vector<SCMByte> globalData;
BreakpointHandler bpHandler;
std::vector<SCMBreakpointInfo> breakpoints;
};
#endif

View File

@ -255,26 +255,6 @@ void RWGame::startScript(const std::string& name)
script = new ScriptMachine(state, f, opcodes);
// Set up breakpoint handler
script->setBreakpointHandler(
[&](const SCMBreakpoint& bp)
{
log.info("Script", "Breakpoint hit!");
std::stringstream ss;
ss << " " << bp.function->description << ".";
ss << " Args:";
for(size_t a = 0; a < bp.args->getParameters().size(); a++)
{
auto& arg = bp.args->getParameters()[a];
ss << " " << arg.integerValue();
if( a != bp.args->getParameters().size()-1 )
{
ss << ",";
}
}
log.info("Script", ss.str());
});
state->script = script;
}
else {