Adds support for step over, step into and step out.

This commit is contained in:
Deukhoofd 2021-10-04 11:03:21 +02:00
parent a2d8293c04
commit d5cc939a6b
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
3 changed files with 84 additions and 4 deletions

View File

@ -37,8 +37,37 @@ void AngelscriptDebugger::on_line_callback(asIScriptContext* ctx, AngelscriptDeb
const char* scriptSection = nullptr; const char* scriptSection = nullptr;
int column = 0; int column = 0;
int line = ctx->GetLineNumber(0, &column, &scriptSection); int line = ctx->GetLineNumber(0, &column, &scriptSection);
if (line == 0) if (line == 0) {
return; return;
}
if (d->_next && d->_nextContext == ctx && d->_nextDepth >= ctx->GetCallstackSize()) {
d->_next = false;
ctx->Suspend();
d->_pausedContexts.push_back(ctx);
auto* o = new DebugAdapterProtocol::StoppedEvent(new DebugAdapterProtocol::StoppedEventBody("step", "", ""));
d->Send(o);
return;
}
if (d->_stepInto && d->_nextContext == ctx) {
d->_stepInto = false;
ctx->Suspend();
d->_pausedContexts.push_back(ctx);
auto* o = new DebugAdapterProtocol::StoppedEvent(new DebugAdapterProtocol::StoppedEventBody("step", "", ""));
d->Send(o);
return;
}
if (d->_stepOut && d->_nextContext == ctx && d->_nextDepth > ctx->GetCallstackSize()) {
d->_stepOut = false;
ctx->Suspend();
d->_pausedContexts.push_back(ctx);
auto* o = new DebugAdapterProtocol::StoppedEvent(new DebugAdapterProtocol::StoppedEventBody("step", "", ""));
d->Send(o);
return;
}
auto resolvedScriptPath = d->GetResolvedScriptPath(scriptSection); auto resolvedScriptPath = d->GetResolvedScriptPath(scriptSection);
auto sectionBreakpoints = d->_breakpoints.find(resolvedScriptPath); auto sectionBreakpoints = d->_breakpoints.find(resolvedScriptPath);
@ -257,7 +286,7 @@ void AngelscriptDebugger::OnRequest(asio::ip::tcp::socket* client, DebugAdapterP
const char* scriptSection = nullptr; const char* scriptSection = nullptr;
int column = 0; int column = 0;
int line; int line;
if (i == 0 && ctx->GetExceptionString() != nullptr) { if (i == 0 && ctx->GetExceptionFunction() != nullptr) {
line = ctx->GetExceptionLineNumber(&column, &scriptSection); line = ctx->GetExceptionLineNumber(&column, &scriptSection);
} else { } else {
line = ctx->GetLineNumber(i, &column, &scriptSection); line = ctx->GetLineNumber(i, &column, &scriptSection);
@ -330,7 +359,48 @@ void AngelscriptDebugger::OnRequest(asio::ip::tcp::socket* client, DebugAdapterP
auto body = new DebugAdapterProtocol::VariablesResponseBody(variables); auto body = new DebugAdapterProtocol::VariablesResponseBody(variables);
response->body = body; response->body = body;
Send(client, response); Send(client, response);
} else if (msg->GetCommand() == "next") {
Next(_pausedContexts.at(0));
} else if (msg->GetCommand() == "stepIn") {
StepInto(_pausedContexts.at(0));
} else if (msg->GetCommand() == "stepOut") {
StepOut(_pausedContexts.at(0));
} else { } else {
std::cout << "Unhandled message: " << msg->GetCommand() << std::endl;
Send(client, new DebugAdapterProtocol::DefinedResponse<DebugAdapterProtocol::ResponseBody, empty>(msg->seq)); Send(client, new DebugAdapterProtocol::DefinedResponse<DebugAdapterProtocol::ResponseBody, empty>(msg->seq));
} }
} }
void AngelscriptDebugger::Next(asIScriptContext* ctx) {
_nextContext = ctx;
_next = true;
_nextDepth = ctx->GetCallstackSize();
_storedVariableReferences.clear();
while (!_pausedContexts.empty()) {
auto* c = _pausedContexts[_pausedContexts.size() - 1];
_pausedContexts.pop_back();
std::thread([](asIScriptContext* c) { c->Execute(); }, c).detach();
}
}
void AngelscriptDebugger::StepInto(asIScriptContext* ctx) {
_nextContext = ctx;
_stepInto = true;
_nextDepth = ctx->GetCallstackSize();
_storedVariableReferences.clear();
while (!_pausedContexts.empty()) {
auto* c = _pausedContexts[_pausedContexts.size() - 1];
_pausedContexts.pop_back();
std::thread([](asIScriptContext* c) { c->Execute(); }, c).detach();
}
}
void AngelscriptDebugger::StepOut(asIScriptContext* ctx) {
_nextContext = ctx;
_stepOut = true;
_nextDepth = ctx->GetCallstackSize();
_storedVariableReferences.clear();
while (!_pausedContexts.empty()) {
auto* c = _pausedContexts[_pausedContexts.size() - 1];
_pausedContexts.pop_back();
std::thread([](asIScriptContext* c) { c->Execute(); }, c).detach();
}
}

View File

@ -56,6 +56,10 @@ private:
void OnRequest(asio::ip::tcp::socket* client, DebugAdapterProtocol::Request* msg); void OnRequest(asio::ip::tcp::socket* client, DebugAdapterProtocol::Request* msg);
std::string GetResolvedScriptPath(const char* scriptSection); std::string GetResolvedScriptPath(const char* scriptSection);
void Next(asIScriptContext* ctx);
void StepInto(asIScriptContext* ctx);
void StepOut(asIScriptContext* ctx);
asio::io_context _ioContext; asio::io_context _ioContext;
asio::ip::tcp::acceptor* _server; asio::ip::tcp::acceptor* _server;
std::unordered_set<asio::ip::tcp::socket*> _connections; std::unordered_set<asio::ip::tcp::socket*> _connections;
@ -64,6 +68,12 @@ private:
std::vector<asIScriptContext*> _pausedContexts; std::vector<asIScriptContext*> _pausedContexts;
std::optional<std::string> _scriptPath; std::optional<std::string> _scriptPath;
asIScriptContext* _nextContext;
bool _next;
size_t _nextDepth;
bool _stepInto;
bool _stepOut;
struct StackScope { struct StackScope {
size_t StackLevel; size_t StackLevel;
uint8_t Type; uint8_t Type;

View File

@ -182,7 +182,7 @@ namespace DebugAdapterProtocol {
EventDefinition(Stopped, "stopped", { EventDefinition(Stopped, "stopped", {
std::string reason; std::string reason;
std::optional<std::string> description; std::optional<std::string> description;
std::optional<size_t> number; std::optional<size_t> threadId = 0;
std::optional<bool> preserveFocusHint = false; std::optional<bool> preserveFocusHint = false;
std::optional<std::string> text; std::optional<std::string> text;
std::optional<bool> allThreadsStopped = true; std::optional<bool> allThreadsStopped = true;
@ -197,7 +197,7 @@ namespace DebugAdapterProtocol {
auto o = EventBody::ToJson(); auto o = EventBody::ToJson();
o["reason"] = reason; o["reason"] = reason;
JsonSerializeOptional(o, description); JsonSerializeOptional(o, description);
JsonSerializeOptional(o, number); JsonSerializeOptional(o, threadId);
JsonSerializeOptional(o, preserveFocusHint); JsonSerializeOptional(o, preserveFocusHint);
JsonSerializeOptional(o, text); JsonSerializeOptional(o, text);
JsonSerializeOptional(o, allThreadsStopped); JsonSerializeOptional(o, allThreadsStopped);