mirror of
https://github.com/polserver/polserver
synced 2026-08-13 08:23:08 -04:00
* Add cppdap debugger library and simple server (#508) * Add cppdap library * Add cppdap server * fixup cmake scripts for windows * Enable caching of cppdap on GitHub actions * Fix CMake for cppdap target * Wait 1s for session close before thread ends * Address review comments - Remove unnecessary use of wait_for - Fix wait_for method * Do not use SocketClientThread for cppdap clients * Address review comments - Cleanup object ownership * Add authorization and event handling (#510) * Add authorization and event handling [WIP] * Use std::weak_ptr; Only allow one debugger conn * Only attach debugger if dbg file exists * Cleanup weak_ptr; Fix listeners; Add handler stubs * Address review comments - PolLock on uoexec and weakptr access - Use make_shared when creating client thread * Add ExecutorDebugListener on_destroy callback * Use cppdap sockets instead of clib sockets * Update cppdap repository to 2703cf4 * Implement server address binding * Update cppdap repository to eeca5ce * Fix warnings * Use weak_from_this * Fix stalled executors on disconnect * Fix stalled executors on re-attach * Clear uoexec weakptr on all debugger detaches * Move server to gamestate * move DapDebugServer into Network namespace * move DapDebugServer into GameState for storage * Move DapDebugServer into NetworkManager * Fix missing memory include * Add more events (#513) * Add more events * Implement dbg_step_out * Fix breakpoint clearing * Add even more events (#515) * add launch request * Add custom `processes` command * fixup loop * Refactoring to move handlers to member functions * Add VariablesRequest and ScopesRequest * use std::varaint for Handles * add pollocks * refactor Handles to new file * move custom messages to proto.h * move clientthread * some formatting / cleanup * Add missing PolLock * move dap variables creation to Handles * appobj members * rename ClientThread to DebugClientThread * rename LaunchRequest args to arg * Fix compiler error on size_t * Add support for EvaluateRequest and SetVariableRequest (#519) * Update grammar for evaluateUnit * Cleanup various compiler code * Add support for EvaluateRequest Only supports values, variables, element access, member access * Add report clearing to reinitialize state * Add support for SetVariableRequest * Fix CI build errors * Move ExpressionEvaluator to Bscript * Fix formatting * Fix include * Refactor global and frame variable references * Encapsulate Executor debugging environment; Fix step over (#524) * Fix step over * Some cleanup of executor - Remove unused debug states - Rename members for consistency * move debugging environment to new class * Move instruction inspection to class * Cleanup slashes on Windows; Add Executor state to processes response (#527) * Fix backspaces in script names on Windows * Fix compilation warnings with data loss * Use boost::icontains for string comparison * Add Executor state to processes response * Updates for libfmt * Fix tests; Fix cppdap build for Mac universal binary (#607) * fix tests * fix cppdap build for mac universal binary * Update cppdap to 2a4c7cf * Add tests; Modify launch behavior to not stop at entry (redo) (#609) * Remove unused setExceptionBreakpoints handler * Add debugger tests * Launching a script should not set attaching state * Add launch tests * Do not check for connection in debugger tests * Rename `program` to `script` in protocol structs * Fix launch stopAtEntry; quote string var values * Fix compilation error on Windows * Add configfiles doc entry * Various fixes for finishing touches; Add core-changes (#610) * switch cmake projects * simple docs * cmake move make_directory * Fix launch request with relative, absolute, package paths * make relative paths as absolute in source request * Add true, false, uninit to ExpressionEvaluator * Re-add setExceptionBreakpoints to avoid unhandled message errors * Better debug thread logging with instance numbers * launched scripts should terminate on disconnect (according to DAP spec) * Properly handle exited event in client thread * Add core-changes * Address Discord comments - Mention vscode-escript in core-changes - Re-add "cppdap already built" in cmake * change cmake escriptgrammarlib visibility to public
207 lines
5.5 KiB
C++
207 lines
5.5 KiB
C++
#include "handles.h"
|
|
|
|
#include "../../bscript/eprog.h"
|
|
#include "../uoexec.h"
|
|
namespace Pol
|
|
{
|
|
namespace Network
|
|
{
|
|
namespace DAP
|
|
{
|
|
using namespace Bscript;
|
|
|
|
Handles::Handles() : _nextHandle( START_HANDLE ) {}
|
|
|
|
void Handles::reset()
|
|
{
|
|
_nextHandle = START_HANDLE;
|
|
_handleMap.clear();
|
|
}
|
|
|
|
int Handles::create( const Reference& value )
|
|
{
|
|
int handle = _nextHandle++;
|
|
_handleMap.insert( { handle, value } );
|
|
return handle;
|
|
}
|
|
|
|
Reference* Handles::get( int handle )
|
|
{
|
|
auto iter = _handleMap.find( handle );
|
|
if ( iter != _handleMap.end() )
|
|
{
|
|
return &iter->second;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
BObjectRef Handles::set_index_or_member( const BObjectRef& objref, const std::string& key,
|
|
BObjectRef& value )
|
|
{
|
|
auto impptr = objref->impptr();
|
|
|
|
if ( impptr != nullptr )
|
|
{
|
|
if ( impptr->isa( BObjectImp::OTStruct ) )
|
|
{
|
|
BStruct* bstruct = static_cast<BStruct*>( impptr );
|
|
bstruct->addMember( key.c_str(), value );
|
|
return value;
|
|
}
|
|
else if ( impptr->isa( BObjectImp::OTDictionary ) )
|
|
{
|
|
BDictionary* dict = static_cast<BDictionary*>( impptr );
|
|
dict->addMember( key.c_str(), value );
|
|
return value;
|
|
}
|
|
else if ( impptr->isa( BObjectImp::OTArray ) )
|
|
{
|
|
ObjArray* objarr = static_cast<ObjArray*>( impptr );
|
|
auto index = strtoul( key.c_str(), nullptr, 0 );
|
|
objarr->ref_arr.at( index ) = value;
|
|
return value;
|
|
}
|
|
else if ( impptr->isa( BObjectImp::OTApplicObj ) )
|
|
{
|
|
impptr->set_member( key.c_str(), value->impptr(), true );
|
|
return impptr->get_member( key.c_str() );
|
|
}
|
|
}
|
|
return BObjectRef( UninitObject::create() );
|
|
}
|
|
|
|
dap::array<dap::Variable> Handles::to_variables( const BObjectRef& objref )
|
|
{
|
|
dap::array<dap::Variable> variables;
|
|
auto impptr = objref->impptr();
|
|
|
|
if ( impptr != nullptr )
|
|
{
|
|
if ( impptr->isa( BObjectImp::OTStruct ) )
|
|
{
|
|
BStruct* bstruct = static_cast<BStruct*>( impptr );
|
|
|
|
for ( const auto& content : bstruct->contents() )
|
|
{
|
|
dap::Variable current_var;
|
|
current_var.name = content.first;
|
|
set_response_details( content.second, current_var );
|
|
variables.push_back( current_var );
|
|
}
|
|
}
|
|
else if ( impptr->isa( BObjectImp::OTDictionary ) )
|
|
{
|
|
BDictionary* dict = static_cast<BDictionary*>( impptr );
|
|
for ( const auto& content : dict->contents() )
|
|
{
|
|
dap::Variable current_var;
|
|
current_var.name = content.first->getStringRep();
|
|
set_response_details( content.second, current_var );
|
|
variables.push_back( current_var );
|
|
}
|
|
}
|
|
else if ( impptr->isa( BObjectImp::OTArray ) )
|
|
{
|
|
ObjArray* objarr = static_cast<ObjArray*>( impptr );
|
|
size_t index = 1;
|
|
for ( const auto& content : objarr->ref_arr )
|
|
{
|
|
dap::Variable current_var;
|
|
current_var.name = Clib::tostring( index++ );
|
|
set_response_details( content, current_var );
|
|
variables.push_back( current_var );
|
|
}
|
|
}
|
|
else if ( impptr->isa( BObjectImp::OTApplicObj ) )
|
|
{
|
|
for ( int i = 0; i < Bscript::n_objmembers; ++i )
|
|
{
|
|
const auto& object_member = Bscript::object_members[i];
|
|
auto member_value = impptr->get_member_id( object_member.id );
|
|
if ( !member_value->isa( BObjectImp::BObjectType::OTUninit ) )
|
|
{
|
|
dap::Variable variable;
|
|
variable.name = object_member.code;
|
|
set_response_details( member_value, variable );
|
|
variables.push_back( variable );
|
|
}
|
|
}
|
|
|
|
std::sort( variables.begin(), variables.end(),
|
|
[]( const auto& a, const auto& b ) { return a.name < b.name; } );
|
|
}
|
|
}
|
|
return variables;
|
|
}
|
|
|
|
FrameReference::FrameReference( Core::UOExecutor* uoexec, Bscript::EScriptProgram* _script,
|
|
size_t frameId )
|
|
: contents()
|
|
{
|
|
if ( frameId > uoexec->ControlStack.size() )
|
|
{
|
|
throw std::runtime_error( "Invalid frame id" );
|
|
}
|
|
|
|
std::vector<BObjectRefVec*> upperLocals2 = uoexec->upperLocals2;
|
|
std::vector<ReturnContext> stack = uoexec->ControlStack;
|
|
|
|
unsigned int PC;
|
|
|
|
{
|
|
ReturnContext rc;
|
|
rc.PC = uoexec->PC;
|
|
rc.ValueStackDepth = static_cast<unsigned int>( uoexec->ValueStack.size() );
|
|
stack.push_back( rc );
|
|
}
|
|
|
|
upperLocals2.push_back( uoexec->Locals2 );
|
|
|
|
auto currentFrameId = stack.size();
|
|
|
|
while ( --currentFrameId, !stack.empty() )
|
|
{
|
|
ReturnContext& rc = stack.back();
|
|
BObjectRefVec* Locals2 = upperLocals2.back();
|
|
PC = rc.PC;
|
|
stack.pop_back();
|
|
upperLocals2.pop_back();
|
|
|
|
if ( frameId != currentFrameId )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
size_t left = Locals2->size();
|
|
|
|
unsigned block = _script->dbg_ins_blocks[PC];
|
|
while ( left )
|
|
{
|
|
while ( left <= _script->blocks[block].parentvariables )
|
|
{
|
|
block = _script->blocks[block].parentblockidx;
|
|
}
|
|
const EPDbgBlock& progblock = _script->blocks[block];
|
|
size_t varidx = left - 1 - progblock.parentvariables;
|
|
left--;
|
|
contents[progblock.localvarnames[varidx]] = &( *Locals2 )[left];
|
|
}
|
|
}
|
|
}
|
|
|
|
GlobalReference::GlobalReference( Core::UOExecutor* uoexec, Bscript::EScriptProgram* _script )
|
|
: contents()
|
|
{
|
|
BObjectRefVec::iterator itr = uoexec->Globals2.begin(), end = uoexec->Globals2.end();
|
|
|
|
for ( unsigned idx = 0; itr != end; ++itr, ++idx )
|
|
{
|
|
if ( _script->globalvarnames.size() > idx )
|
|
{
|
|
contents[_script->globalvarnames[idx]] = &( *itr );
|
|
}
|
|
}
|
|
}
|
|
} // namespace DAP
|
|
} // namespace Network
|
|
} // namespace Pol
|