Debugger: Cleanup.

Team:
- Remove expression evaluation event / listener hook. This doesn't
  really belong to the Team anyways.

UserInterfaceListener:
- ExpressionEvaluationRequested() now takes an ExpressionInfo object
  rather than the individual subcomponents.

ExpressionEvaluationJob:
- Notification of expression evaluation completion is now handled
  via the info object's listener interface rather than the Team.

Others:
- Adjust all users of expressions to set themselves up as
  ExpressionInfo::Listener subclasses, and consequently add themselves
  to the respective info object when requesting evaluation. This
  significantly simplifies various things, and also ensures that no
  one accidentally gets notified of an expression they didn't actually
  ask for, which could occur with the previous Team-based listener
  interface. Make all other required adjustments for new interface
  usage.

No functional change intended.
This commit is contained in:
Rene Gollent
2014-11-08 18:42:53 -05:00
parent 05d1068c97
commit d1c9ffed34
22 changed files with 310 additions and 352 deletions
+18 -20
View File
@@ -28,6 +28,7 @@
#include "CpuState.h" #include "CpuState.h"
#include "DebuggerInterface.h" #include "DebuggerInterface.h"
#include "DebugReportGenerator.h" #include "DebugReportGenerator.h"
#include "ExpressionInfo.h"
#include "FileManager.h" #include "FileManager.h"
#include "Function.h" #include "Function.h"
#include "FunctionID.h" #include "FunctionID.h"
@@ -751,19 +752,17 @@ TeamDebugger::MessageReceived(BMessage* message)
} }
// ExpressionEvaluationRequested() acquires a reference // ExpressionEvaluationRequested() acquires a reference
// on our behalf. // to both the language and the expression info on our behalf.
BReference<SourceLanguage> reference(language, true); BReference<SourceLanguage> reference(language, true);
const char* expression; ExpressionInfo* info;
if (message->FindString("expression", &expression) != B_OK) if (message->FindPointer("info",
break; reinterpret_cast<void**>(&info)) != B_OK) {
type_code resultType;
if (message->FindInt32("type",
reinterpret_cast<int32*>(&resultType)) != B_OK) {
break; break;
} }
BReference<ExpressionInfo> infoReference(info, true);
StackFrame* frame; StackFrame* frame;
if (message->FindPointer("frame", if (message->FindPointer("frame",
reinterpret_cast<void**>(&frame)) != B_OK) { reinterpret_cast<void**>(&frame)) != B_OK) {
@@ -780,8 +779,7 @@ TeamDebugger::MessageReceived(BMessage* message)
thread = NULL; thread = NULL;
} }
_HandleEvaluateExpression(language, expression, resultType, _HandleEvaluateExpression(language, info, frame, thread);
frame, thread);
break; break;
} }
@@ -1162,21 +1160,22 @@ TeamDebugger::InspectRequested(target_addr_t address,
void void
TeamDebugger::ExpressionEvaluationRequested(SourceLanguage* language, TeamDebugger::ExpressionEvaluationRequested(SourceLanguage* language,
const char* expression, type_code resultType, StackFrame* frame, ExpressionInfo* info, StackFrame* frame, ::Thread* thread)
::Thread* thread)
{ {
BMessage message(MSG_EVALUATE_EXPRESSION); BMessage message(MSG_EVALUATE_EXPRESSION);
message.AddPointer("language", language); message.AddPointer("language", language);
message.AddString("expression", expression); message.AddPointer("info", info);
message.AddInt32("type", resultType);
if (frame != NULL) if (frame != NULL)
message.AddPointer("frame", frame); message.AddPointer("frame", frame);
if (thread != NULL) if (thread != NULL)
message.AddPointer("thread", thread); message.AddPointer("thread", thread);
BReference<SourceLanguage> reference(language); BReference<SourceLanguage> languageReference(language);
if (PostMessage(&message) == B_OK) BReference<ExpressionInfo> infoReference(info);
reference.Detach(); if (PostMessage(&message) == B_OK) {
languageReference.Detach();
infoReference.Detach();
}
} }
@@ -2060,12 +2059,11 @@ TeamDebugger::_HandleInspectAddress(target_addr_t address,
void void
TeamDebugger::_HandleEvaluateExpression(SourceLanguage* language, TeamDebugger::_HandleEvaluateExpression(SourceLanguage* language,
const char* expression, type_code resultType, StackFrame* frame, ExpressionInfo* info, StackFrame* frame, ::Thread* thread)
::Thread* thread)
{ {
status_t result = fWorker->ScheduleJob( status_t result = fWorker->ScheduleJob(
new(std::nothrow) ExpressionEvaluationJob(fTeam, fDebuggerInterface, new(std::nothrow) ExpressionEvaluationJob(fTeam, fDebuggerInterface,
language, expression, resultType, frame, thread)); language, info, frame, thread));
if (result != B_OK) { if (result != B_OK) {
_NotifyUser("Evaluate Expression", "Failed to evaluate expression: %s", _NotifyUser("Evaluate Expression", "Failed to evaluate expression: %s",
strerror(result)); strerror(result));
+2 -4
View File
@@ -110,8 +110,7 @@ private:
virtual void ExpressionEvaluationRequested( virtual void ExpressionEvaluationRequested(
SourceLanguage* language, SourceLanguage* language,
const char* expression, ExpressionInfo* info,
type_code resultType,
StackFrame* frame = NULL, StackFrame* frame = NULL,
::Thread* thread = NULL); ::Thread* thread = NULL);
@@ -198,8 +197,7 @@ private:
void _HandleEvaluateExpression( void _HandleEvaluateExpression(
SourceLanguage* language, SourceLanguage* language,
const char* expression, ExpressionInfo* info,
type_code resultType,
StackFrame* frame, StackFrame* frame,
::Thread* thread); ::Thread* thread);
+29 -23
View File
@@ -19,6 +19,7 @@
#include "BreakpointManager.h" #include "BreakpointManager.h"
#include "CpuState.h" #include "CpuState.h"
#include "DebuggerInterface.h" #include "DebuggerInterface.h"
#include "ExpressionInfo.h"
#include "FunctionInstance.h" #include "FunctionInstance.h"
#include "ImageDebugInfo.h" #include "ImageDebugInfo.h"
#include "InstructionInfo.h" #include "InstructionInfo.h"
@@ -30,6 +31,7 @@
#include "SpecificImageDebugInfo.h" #include "SpecificImageDebugInfo.h"
#include "StackTrace.h" #include "StackTrace.h"
#include "Statement.h" #include "Statement.h"
#include "SyntheticPrimitiveType.h"
#include "Team.h" #include "Team.h"
#include "Tracing.h" #include "Tracing.h"
#include "Value.h" #include "Value.h"
@@ -46,38 +48,26 @@ enum {
}; };
class ExpressionJobListener : public JobListener { class ExpressionEvaluationListener : public ExpressionInfo::Listener {
public: public:
ExpressionJobListener(ThreadHandler* handler) ExpressionEvaluationListener(ThreadHandler* handler)
: :
JobListener(),
fHandler(handler) fHandler(handler)
{ {
fHandler->AcquireReference(); fHandler->AcquireReference();
} }
~ExpressionJobListener() ~ExpressionEvaluationListener()
{ {
fHandler->ReleaseReference(); fHandler->ReleaseReference();
} }
virtual void JobDone(Job* job) virtual void ExpressionEvaluated(ExpressionInfo* info, status_t result,
Value* value)
{ {
Value* resultValue = dynamic_cast<ExpressionEvaluationJob*>(job) fHandler->_HandleBreakpointConditionEvaluated(value);
->GetResultValue();
fHandler->_HandleBreakpointConditionEvaluated(resultValue);
} }
virtual void JobFailed(Job* job)
{
fHandler->_HandleBreakpointConditionEvaluated(NULL);
}
virtual void JobAborted(Job* job)
{
fHandler->_HandleBreakpointConditionEvaluated(NULL);
}
private: private:
ThreadHandler* fHandler; ThreadHandler* fHandler;
}; };
@@ -893,17 +883,33 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState)
return false; return false;
BReference<SourceLanguage> reference(language, true); BReference<SourceLanguage> reference(language, true);
ExpressionJobListener* listener ExpressionEvaluationListener* listener
= new(std::nothrow) ExpressionJobListener(this); = new(std::nothrow) ExpressionEvaluationListener(this);
if (listener == NULL) if (listener == NULL)
return false; return false;
Type* type = new(std::nothrow) SyntheticPrimitiveType(B_UINT64_TYPE);
if (type == NULL)
return false;
BReference<Type> typeReference(type, true);
ExpressionInfo* expressionInfo = new(std::nothrow) ExpressionInfo(
userBreakpoint->Condition(), type);
if (expressionInfo == NULL)
return false;
BReference<ExpressionInfo> expressionReference(expressionInfo, true);
expressionInfo->AddListener(listener);
status_t error = fWorker->ScheduleJob( status_t error = fWorker->ScheduleJob(
new(std::nothrow) ExpressionEvaluationJob(fThread->GetTeam(), new(std::nothrow) ExpressionEvaluationJob(fThread->GetTeam(),
fDebuggerInterface, language, userBreakpoint->Condition(), fDebuggerInterface, language, expressionInfo, frame, fThread));
B_UINT64_TYPE, frame, fThread), listener);
BPrivate::ObjectDeleter<ExpressionJobListener> deleter(listener); BPrivate::ObjectDeleter<ExpressionEvaluationListener> deleter(
listener);
if (error == B_OK) { if (error == B_OK) {
_SetThreadState(THREAD_STATE_STOPPED, cpuState, _SetThreadState(THREAD_STATE_STOPPED, cpuState,
THREAD_STOPPED_BREAKPOINT, BString()); THREAD_STOPPED_BREAKPOINT, BString());
@@ -66,7 +66,7 @@ public:
void HandleStackTraceChanged(); void HandleStackTraceChanged();
private: private:
friend class ExpressionJobListener; friend class ExpressionEvaluationListener;
private: private:
// ImageDebugInfoProvider // ImageDebugInfoProvider
@@ -10,10 +10,12 @@
#include <AutoLocker.h> #include <AutoLocker.h>
#include "DebuggerInterface.h" #include "DebuggerInterface.h"
#include "ExpressionInfo.h"
#include "SourceLanguage.h" #include "SourceLanguage.h"
#include "StackFrame.h" #include "StackFrame.h"
#include "Team.h" #include "Team.h"
#include "Thread.h" #include "Thread.h"
#include "Type.h"
#include "Value.h" #include "Value.h"
#include "ValueNode.h" #include "ValueNode.h"
#include "ValueNodeManager.h" #include "ValueNodeManager.h"
@@ -21,23 +23,24 @@
ExpressionEvaluationJob::ExpressionEvaluationJob(Team* team, ExpressionEvaluationJob::ExpressionEvaluationJob(Team* team,
DebuggerInterface* debuggerInterface, SourceLanguage* language, DebuggerInterface* debuggerInterface, SourceLanguage* language,
const char* expression, type_code resultType, StackFrame* frame, ExpressionInfo* info, StackFrame* frame,
Thread* thread) Thread* thread)
: :
fKey(expression, JOB_TYPE_EVALUATE_EXPRESSION), fKey(info->Expression(), JOB_TYPE_EVALUATE_EXPRESSION),
fTeam(team), fTeam(team),
fDebuggerInterface(debuggerInterface), fDebuggerInterface(debuggerInterface),
fArchitecture(debuggerInterface->GetArchitecture()), fArchitecture(debuggerInterface->GetArchitecture()),
fTypeInformation(team->GetTeamTypeInformation()), fTypeInformation(team->GetTeamTypeInformation()),
fLanguage(language), fLanguage(language),
fExpression(expression), fExpressionInfo(info),
fResultType(resultType),
fFrame(frame), fFrame(frame),
fThread(thread), fThread(thread),
fManager(NULL), fManager(NULL),
fResultValue(NULL) fResultValue(NULL)
{ {
fLanguage->AcquireReference(); fLanguage->AcquireReference();
fExpressionInfo->AcquireReference();
if (fFrame != NULL) if (fFrame != NULL)
fFrame->AcquireReference(); fFrame->AcquireReference();
if (fThread != NULL) if (fThread != NULL)
@@ -48,6 +51,7 @@ ExpressionEvaluationJob::ExpressionEvaluationJob(Team* team,
ExpressionEvaluationJob::~ExpressionEvaluationJob() ExpressionEvaluationJob::~ExpressionEvaluationJob()
{ {
fLanguage->ReleaseReference(); fLanguage->ReleaseReference();
fExpressionInfo->ReleaseReference();
if (fFrame != NULL) if (fFrame != NULL)
fFrame->ReleaseReference(); fFrame->ReleaseReference();
if (fThread != NULL) if (fThread != NULL)
@@ -80,13 +84,15 @@ ExpressionEvaluationJob::Do()
} }
if (result != B_OK) { if (result != B_OK) {
fTeam->NotifyExpressionEvaluated(fExpression.String(), result, NULL); fExpressionInfo->NotifyExpressionEvaluated(result, NULL);
return result; return result;
} }
ValueNode* neededNode = NULL; ValueNode* neededNode = NULL;
result = fLanguage->EvaluateExpression(fExpression, PrimitiveType* type = dynamic_cast<PrimitiveType*>(
fResultType, fManager, fResultValue, neededNode); fExpressionInfo->ResultType());
result = fLanguage->EvaluateExpression(fExpressionInfo->Expression(),
type->TypeConstant(), fManager, fResultValue, neededNode);
if (neededNode != NULL) { if (neededNode != NULL) {
result = ResolveNodeValue(neededNode); result = ResolveNodeValue(neededNode);
if (State() == JOB_STATE_WAITING) if (State() == JOB_STATE_WAITING)
@@ -94,9 +100,7 @@ ExpressionEvaluationJob::Do()
// if result != B_OK, fall through // if result != B_OK, fall through
} }
AutoLocker<Team> teamLocker(fTeam); fExpressionInfo->NotifyExpressionEvaluated(result, fResultValue);
fTeam->NotifyExpressionEvaluated(fExpression.String(), result,
fResultValue);
return B_OK; return B_OK;
} }
+3 -4
View File
@@ -18,6 +18,7 @@ class Architecture;
class BVariant; class BVariant;
class CpuState; class CpuState;
class DebuggerInterface; class DebuggerInterface;
class ExpressionInfo;
class Function; class Function;
class FunctionInstance; class FunctionInstance;
class Image; class Image;
@@ -236,8 +237,7 @@ public:
ExpressionEvaluationJob(Team* team, ExpressionEvaluationJob(Team* team,
DebuggerInterface* debuggerInterface, DebuggerInterface* debuggerInterface,
SourceLanguage* language, SourceLanguage* language,
const char* expression, ExpressionInfo* info,
type_code resultType,
StackFrame* frame, StackFrame* frame,
Thread* thread); Thread* thread);
virtual ~ExpressionEvaluationJob(); virtual ~ExpressionEvaluationJob();
@@ -257,8 +257,7 @@ private:
Architecture* fArchitecture; Architecture* fArchitecture;
TeamTypeInformation* fTypeInformation; TeamTypeInformation* fTypeInformation;
SourceLanguage* fLanguage; SourceLanguage* fLanguage;
BString fExpression; ExpressionInfo* fExpressionInfo;
type_code fResultType;
StackFrame* fFrame; StackFrame* fFrame;
Thread* fThread; Thread* fThread;
ValueNodeManager* fManager; ValueNodeManager* fManager;
-43
View File
@@ -732,19 +732,6 @@ Team::NotifyDebugReportChanged(const char* reportPath)
} }
void
Team::NotifyExpressionEvaluated(const char* expression, status_t result,
Value* value)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->ExpressionEvaluated(ExpressionEvaluationEvent(
TEAM_EVENT_EXPRESSION_EVALUATED, this, expression, result,
value));
}
}
void void
Team::_NotifyThreadAdded(Thread* thread) Team::_NotifyThreadAdded(Thread* thread)
{ {
@@ -904,29 +891,6 @@ Team::UserBreakpointEvent::UserBreakpointEvent(uint32 type, Team* team,
} }
// #pragma mark - ExpressionEvaluationEvent
Team::ExpressionEvaluationEvent::ExpressionEvaluationEvent(uint32 type,
Team* team, const char* expression, status_t result, Value* value)
:
Event(type, team),
fExpression(expression),
fEvaluationResult(result),
fValue(value)
{
if (fValue != NULL)
fValue->AcquireReference();
}
Team::ExpressionEvaluationEvent::~ExpressionEvaluationEvent()
{
if (fValue != NULL)
fValue->ReleaseReference();
}
// #pragma mark - Listener // #pragma mark - Listener
@@ -1049,10 +1013,3 @@ void
Team::Listener::DebugReportChanged(const Team::DebugReportEvent& event) Team::Listener::DebugReportChanged(const Team::DebugReportEvent& event)
{ {
} }
void
Team::Listener::ExpressionEvaluated(
const Team::ExpressionEvaluationEvent& event)
{
}
+1 -32
View File
@@ -48,9 +48,7 @@ enum {
TEAM_EVENT_WATCHPOINT_REMOVED, TEAM_EVENT_WATCHPOINT_REMOVED,
TEAM_EVENT_WATCHPOINT_CHANGED, TEAM_EVENT_WATCHPOINT_CHANGED,
TEAM_EVENT_DEBUG_REPORT_CHANGED, TEAM_EVENT_DEBUG_REPORT_CHANGED
TEAM_EVENT_EXPRESSION_EVALUATED
}; };
@@ -77,7 +75,6 @@ public:
class BreakpointEvent; class BreakpointEvent;
class ConsoleOutputEvent; class ConsoleOutputEvent;
class DebugReportEvent; class DebugReportEvent;
class ExpressionEvaluationEvent;
class ImageEvent; class ImageEvent;
class ImageLoadEvent; class ImageLoadEvent;
class ImageLoadNameEvent; class ImageLoadNameEvent;
@@ -228,11 +225,6 @@ public:
void NotifyDebugReportChanged( void NotifyDebugReportChanged(
const char* reportPath); const char* reportPath);
// expression evaluation related service methods
void NotifyExpressionEvaluated(
const char* expression,
status_t result, Value* value);
private: private:
struct BreakpointByAddressPredicate; struct BreakpointByAddressPredicate;
struct WatchpointByAddressPredicate; struct WatchpointByAddressPredicate;
@@ -392,25 +384,6 @@ protected:
}; };
class Team::ExpressionEvaluationEvent : public Event {
public:
ExpressionEvaluationEvent(uint32 type,
Team* team, const char* expression,
status_t result, Value* value);
virtual ~ExpressionEvaluationEvent();
status_t GetResult() const
{ return fEvaluationResult; }
BString GetExpression() const { return fExpression; }
Value* GetValue() const { return fValue; }
protected:
BString fExpression;
status_t fEvaluationResult;
Value* fValue;
};
class Team::Listener : public DoublyLinkedListLinkImpl<Team::Listener> { class Team::Listener : public DoublyLinkedListLinkImpl<Team::Listener> {
public: public:
virtual ~Listener(); virtual ~Listener();
@@ -455,10 +428,6 @@ public:
virtual void WatchpointChanged( virtual void WatchpointChanged(
const Team::WatchpointEvent& event); const Team::WatchpointEvent& event);
virtual void ExpressionEvaluated(
const Team::ExpressionEvaluationEvent&
event);
virtual void DebugReportChanged( virtual void DebugReportChanged(
const Team::DebugReportEvent& event); const Team::DebugReportEvent& event);
}; };
@@ -18,6 +18,7 @@
class entry_ref; class entry_ref;
class CpuState; class CpuState;
class ExpressionInfo;
class FunctionInstance; class FunctionInstance;
class Image; class Image;
class LocatableFile; class LocatableFile;
@@ -144,8 +145,7 @@ public:
virtual void ExpressionEvaluationRequested( virtual void ExpressionEvaluationRequested(
SourceLanguage* language, SourceLanguage* language,
const char* expression, ExpressionInfo* info,
type_code resultType,
StackFrame* frame = NULL, StackFrame* frame = NULL,
Thread* thread = NULL) = 0; Thread* thread = NULL) = 0;
@@ -28,13 +28,13 @@ static CliContext* sCurrentContext;
struct CliContext::Event : DoublyLinkedListLinkImpl<CliContext::Event> { struct CliContext::Event : DoublyLinkedListLinkImpl<CliContext::Event> {
Event(int type, Thread* thread = NULL, TeamMemoryBlock* block = NULL, Event(int type, Thread* thread = NULL, TeamMemoryBlock* block = NULL,
const char* expression = NULL, status_t expressionResult = B_OK, ExpressionInfo* info = NULL, status_t expressionResult = B_OK,
Value* expressionValue = NULL) Value* expressionValue = NULL)
: :
fType(type), fType(type),
fThreadReference(thread), fThreadReference(thread),
fMemoryBlockReference(block), fMemoryBlockReference(block),
fExpression(expression), fExpressionInfo(info),
fExpressionResult(expressionResult), fExpressionResult(expressionResult),
fExpressionValue(expressionValue) fExpressionValue(expressionValue)
{ {
@@ -55,9 +55,9 @@ struct CliContext::Event : DoublyLinkedListLinkImpl<CliContext::Event> {
return fMemoryBlockReference.Get(); return fMemoryBlockReference.Get();
} }
const BString& GetExpression() const ExpressionInfo* GetExpressionInfo() const
{ {
return fExpression; return fExpressionInfo;
} }
status_t GetExpressionResult() const status_t GetExpressionResult() const
@@ -75,7 +75,7 @@ private:
int fType; int fType;
BReference<Thread> fThreadReference; BReference<Thread> fThreadReference;
BReference<TeamMemoryBlock> fMemoryBlockReference; BReference<TeamMemoryBlock> fMemoryBlockReference;
BString fExpression; BReference<ExpressionInfo> fExpressionInfo;
status_t fExpressionResult; status_t fExpressionResult;
BReference<Value> fExpressionValue; BReference<Value> fExpressionValue;
}; };
@@ -103,7 +103,7 @@ CliContext::CliContext()
fCurrentStackTrace(NULL), fCurrentStackTrace(NULL),
fCurrentStackFrameIndex(-1), fCurrentStackFrameIndex(-1),
fCurrentBlock(NULL), fCurrentBlock(NULL),
fCurrentExpression(NULL), fExpressionInfo(NULL),
fExpressionResult(B_OK), fExpressionResult(B_OK),
fExpressionValue(NULL) fExpressionValue(NULL)
{ {
@@ -157,6 +157,11 @@ CliContext::Init(Team* team, UserInterfaceListener* listener)
return B_NO_MEMORY; return B_NO_MEMORY;
fNodeManager->AddListener(this); fNodeManager->AddListener(this);
fExpressionInfo = new(std::nothrow) ExpressionInfo();
if (fExpressionInfo == NULL)
return B_NO_MEMORY;
fExpressionInfo->AddListener(this);
return B_OK; return B_OK;
} }
@@ -193,6 +198,11 @@ CliContext::Cleanup()
fCurrentBlock->ReleaseReference(); fCurrentBlock->ReleaseReference();
fCurrentBlock = NULL; fCurrentBlock = NULL;
} }
if (fExpressionInfo != NULL) {
fExpressionInfo->ReleaseReference();
fExpressionInfo = NULL;
}
} }
@@ -285,13 +295,6 @@ CliContext::SetCurrentStackFrameIndex(int32 index)
} }
void
CliContext::SetCurrentExpression(const char* expression)
{
fCurrentExpression = expression;
}
const char* const char*
CliContext::PromptUser(const char* prompt) CliContext::PromptUser(const char* prompt)
{ {
@@ -440,17 +443,14 @@ CliContext::ProcessPendingEvents()
fCurrentBlock = event->GetMemoryBlock(); fCurrentBlock = event->GetMemoryBlock();
break; break;
case EVENT_EXPRESSION_EVALUATED: case EVENT_EXPRESSION_EVALUATED:
if (event->GetExpression() == fCurrentExpression) { fExpressionResult = event->GetExpressionResult();
fCurrentExpression = NULL; if (fExpressionValue != NULL) {
fExpressionResult = event->GetExpressionResult(); fExpressionValue->ReleaseReference();
if (fExpressionValue != NULL) { fExpressionValue = NULL;
fExpressionValue->ReleaseReference();
fExpressionValue = NULL;
}
fExpressionValue = event->GetExpressionValue();
if (fExpressionValue != NULL)
fExpressionValue->AcquireReference();
} }
fExpressionValue = event->GetExpressionValue();
if (fExpressionValue != NULL)
fExpressionValue->AcquireReference();
break; break;
case EVENT_DEBUG_REPORT_CHANGED: case EVENT_DEBUG_REPORT_CHANGED:
if (!IsInteractive()) { if (!IsInteractive()) {
@@ -508,12 +508,12 @@ CliContext::ThreadStackTraceChanged(const Team::ThreadEvent& threadEvent)
void void
CliContext::ExpressionEvaluated(const Team::ExpressionEvaluationEvent& event) CliContext::ExpressionEvaluated(ExpressionInfo* info, status_t result,
Value* value)
{ {
_QueueEvent( _QueueEvent(
new(std::nothrow) Event(EVENT_EXPRESSION_EVALUATED, new(std::nothrow) Event(EVENT_EXPRESSION_EVALUATED,
NULL, NULL, event.GetExpression(), event.GetResult(), NULL, NULL, info, result, value));
event.GetValue()));
_SignalInputLoop(EVENT_EXPRESSION_EVALUATED); _SignalInputLoop(EVENT_EXPRESSION_EVALUATED);
} }
@@ -13,6 +13,7 @@
#include <Locker.h> #include <Locker.h>
#include "ExpressionInfo.h"
#include "Team.h" #include "Team.h"
#include "TeamMemoryBlock.h" #include "TeamMemoryBlock.h"
#include "ValueNodeContainer.h" #include "ValueNodeContainer.h"
@@ -28,6 +29,7 @@ class ValueNodeManager;
class CliContext : private Team::Listener, class CliContext : private Team::Listener,
public TeamMemoryBlock::Listener, public TeamMemoryBlock::Listener,
public ExpressionInfo::Listener,
private ValueNodeContainer::Listener { private ValueNodeContainer::Listener {
public: public:
enum { enum {
@@ -79,8 +81,8 @@ public:
TeamMemoryBlock* CurrentBlock() const { return fCurrentBlock; } TeamMemoryBlock* CurrentBlock() const { return fCurrentBlock; }
void SetCurrentExpression(const char* expression); ExpressionInfo* GetExpressionInfo() const
{ return fExpressionInfo; }
status_t GetExpressionResult() const status_t GetExpressionResult() const
{ return fExpressionResult; } { return fExpressionResult; }
Value* GetExpressionValue() const Value* GetExpressionValue() const
@@ -110,16 +112,16 @@ private:
virtual void ThreadStackTraceChanged( virtual void ThreadStackTraceChanged(
const Team::ThreadEvent& event); const Team::ThreadEvent& event);
virtual void ExpressionEvaluated(
const Team::ExpressionEvaluationEvent&
event);
virtual void DebugReportChanged( virtual void DebugReportChanged(
const Team::DebugReportEvent& event); const Team::DebugReportEvent& event);
// TeamMemoryBlock::Listener // TeamMemoryBlock::Listener
virtual void MemoryBlockRetrieved(TeamMemoryBlock* block); virtual void MemoryBlockRetrieved(TeamMemoryBlock* block);
// ExpressionInfo::Listener
virtual void ExpressionEvaluated(ExpressionInfo* info,
status_t result, Value* value);
// ValueNodeContainer::Listener // ValueNodeContainer::Listener
virtual void ValueNodeChanged(ValueNodeChild* nodeChild, virtual void ValueNodeChanged(ValueNodeChild* nodeChild,
ValueNode* oldNode, ValueNode* newNode); ValueNode* oldNode, ValueNode* newNode);
@@ -156,7 +158,7 @@ private:
int32 fCurrentStackFrameIndex; int32 fCurrentStackFrameIndex;
TeamMemoryBlock* fCurrentBlock; TeamMemoryBlock* fCurrentBlock;
const char* fCurrentExpression; ExpressionInfo* fExpressionInfo;
status_t fExpressionResult; status_t fExpressionResult;
Value* fExpressionValue; Value* fExpressionValue;
@@ -18,7 +18,7 @@
#include "CliContext.h" #include "CliContext.h"
#include "CppLanguage.h" #include "CppLanguage.h"
#include "Number.h" #include "SyntheticPrimitiveType.h"
#include "Team.h" #include "Team.h"
#include "TeamMemoryBlock.h" #include "TeamMemoryBlock.h"
#include "UiUtils.h" #include "UiUtils.h"
@@ -57,10 +57,28 @@ CliDumpMemoryCommand::Execute(int argc, const char* const* argv,
return; return;
} }
ExpressionInfo* info = context.GetExpressionInfo();
target_addr_t address = 0; target_addr_t address = 0;
context.SetCurrentExpression(argv[1]);
PrimitiveType* type = dynamic_cast<PrimitiveType*>(info->ResultType());
if (type == NULL || type->TypeConstant() != B_UINT64_TYPE) {
type = new(std::nothrow) SyntheticPrimitiveType(
B_UINT64_TYPE);
if (type == NULL) {
printf("Unable to evaluate expression: %s\n", strerror(B_NO_MEMORY));
return;
}
BReference<Type> typeReference(type, true);
info->SetResultType(type);
}
info->SetExpression(argv[1]);
context.GetUserInterfaceListener()->ExpressionEvaluationRequested( context.GetUserInterfaceListener()->ExpressionEvaluationRequested(
fLanguage, argv[1], B_UINT64_TYPE); fLanguage, info);
context.WaitForEvents(CliContext::EVENT_EXPRESSION_EVALUATED); context.WaitForEvents(CliContext::EVENT_EXPRESSION_EVALUATED);
if (context.IsTerminating()) if (context.IsTerminating())
return; return;
@@ -21,7 +21,7 @@
#include "GuiTeamUiSettings.h" #include "GuiTeamUiSettings.h"
#include "MemoryView.h" #include "MemoryView.h"
#include "MessageCodes.h" #include "MessageCodes.h"
#include "Number.h" #include "SyntheticPrimitiveType.h"
#include "Team.h" #include "Team.h"
#include "UserInterface.h" #include "UserInterface.h"
#include "Value.h" #include "Value.h"
@@ -48,10 +48,9 @@ InspectorWindow::InspectorWindow(::Team* team, UserInterfaceListener* listener,
fCurrentAddress(0LL), fCurrentAddress(0LL),
fTeam(team), fTeam(team),
fLanguage(NULL), fLanguage(NULL),
fExpressionInfo(NULL),
fTarget(target) fTarget(target)
{ {
AutoLocker< ::Team> teamLocker(fTeam);
fTeam->AddListener(this);
} }
@@ -62,11 +61,13 @@ InspectorWindow::~InspectorWindow()
fCurrentBlock->ReleaseReference(); fCurrentBlock->ReleaseReference();
} }
AutoLocker< ::Team> teamLocker(fTeam);
fTeam->RemoveListener(this);
if (fLanguage != NULL) if (fLanguage != NULL)
fLanguage->ReleaseReference(); fLanguage->ReleaseReference();
if (fExpressionInfo != NULL) {
fExpressionInfo->RemoveListener(this);
fExpressionInfo->ReleaseReference();
}
} }
@@ -91,6 +92,10 @@ void
InspectorWindow::_Init() InspectorWindow::_Init()
{ {
fLanguage = new CppLanguage(); fLanguage = new CppLanguage();
::Type* type = new SyntheticPrimitiveType(B_UINT64_TYPE);
BReference< ::Type> typeReference(type);
fExpressionInfo = new ExpressionInfo(NULL, type);
fExpressionInfo->AddListener(this);
BScrollView* scrollView; BScrollView* scrollView;
@@ -210,10 +215,13 @@ InspectorWindow::MessageReceived(BMessage* message)
{ {
target_addr_t address = 0; target_addr_t address = 0;
if (message->FindUInt64("address", &address) != B_OK) { if (message->FindUInt64("address", &address) != B_OK) {
fListener->ExpressionEvaluationRequested( if (fAddressInput->TextView()->TextLength() == 0)
fLanguage, break;
fAddressInput->Text(),
B_UINT64_TYPE); fExpressionInfo->SetExpression(fAddressInput->Text());
fListener->ExpressionEvaluationRequested(fLanguage,
fExpressionInfo);
} else } else
_SetToAddress(address); _SetToAddress(address);
break; break;
@@ -356,20 +364,11 @@ InspectorWindow::TargetAddressChanged(target_addr_t address)
void void
InspectorWindow::ExpressionEvaluated( InspectorWindow::ExpressionEvaluated(ExpressionInfo* info, status_t result,
const Team::ExpressionEvaluationEvent& event) Value* value)
{ {
BMessage message(MSG_EXPRESSION_EVALUATED); BMessage message(MSG_EXPRESSION_EVALUATED);
AutoLocker<BLooper> lock(this); message.AddInt32("result", result);
if (!lock.IsLocked())
return;
if (event.GetExpression() != fAddressInput->Text())
return;
lock.Unlock();
message.AddInt32("result", event.GetResult());
Value* value = event.GetValue();
BReference<Value> reference; BReference<Value> reference;
if (value != NULL) { if (value != NULL) {
reference.SetTo(value); reference.SetTo(value);
@@ -8,6 +8,7 @@
#include <Window.h> #include <Window.h>
#include "ExpressionInfo.h"
#include "MemoryView.h" #include "MemoryView.h"
#include "Team.h" #include "Team.h"
#include "TeamMemoryBlock.h" #include "TeamMemoryBlock.h"
@@ -26,7 +27,7 @@ class UserInterfaceListener;
class InspectorWindow : public BWindow, class InspectorWindow : public BWindow,
public TeamMemoryBlock::Listener, public TeamMemoryBlock::Listener,
public MemoryView::Listener, public MemoryView::Listener,
private Team::Listener { private ExpressionInfo::Listener {
public: public:
InspectorWindow(::Team* team, InspectorWindow(::Team* team,
UserInterfaceListener* listener, UserInterfaceListener* listener,
@@ -49,10 +50,9 @@ public:
// MemoryView::Listener // MemoryView::Listener
virtual void TargetAddressChanged(target_addr_t address); virtual void TargetAddressChanged(target_addr_t address);
// Team::Listener // ExpressionInfo::Listener
virtual void ExpressionEvaluated( virtual void ExpressionEvaluated(ExpressionInfo* info,
const Team::ExpressionEvaluationEvent& status_t result, Value* value);
event);
status_t LoadSettings( status_t LoadSettings(
const GuiTeamUiSettings& settings); const GuiTeamUiSettings& settings);
@@ -84,6 +84,7 @@ private:
target_addr_t fCurrentAddress; target_addr_t fCurrentAddress;
::Team* fTeam; ::Team* fTeam;
SourceLanguage* fLanguage; SourceLanguage* fLanguage;
ExpressionInfo* fExpressionInfo;
BHandler* fTarget; BHandler* fTarget;
}; };
@@ -17,6 +17,7 @@
#include "MessageCodes.h" #include "MessageCodes.h"
#include "SourceLanguage.h" #include "SourceLanguage.h"
#include "StackFrame.h" #include "StackFrame.h"
#include "SyntheticPrimitiveType.h"
#include "Thread.h" #include "Thread.h"
#include "UiUtils.h" #include "UiUtils.h"
#include "UserInterface.h" #include "UserInterface.h"
@@ -29,21 +30,20 @@ enum {
ExpressionEvaluationWindow::ExpressionEvaluationWindow( ExpressionEvaluationWindow::ExpressionEvaluationWindow(
::Team* team, SourceLanguage* language, StackFrame* frame, SourceLanguage* language, StackFrame* frame, ::Thread* thread,
::Thread* thread, UserInterfaceListener* listener, BHandler* target) UserInterfaceListener* listener, BHandler* target)
: :
BWindow(BRect(), "Evaluate Expression", B_FLOATING_WINDOW, BWindow(BRect(), "Evaluate Expression", B_FLOATING_WINDOW,
B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
fTeam(team),
fLanguage(language), fLanguage(language),
fExpressionInfo(NULL),
fExpressionInput(NULL), fExpressionInput(NULL),
fExpressionOutput(NULL), fExpressionOutput(NULL),
fEvaluateButton(NULL), fEvaluateButton(NULL),
fListener(listener), fListener(listener),
fStackFrame(frame), fStackFrame(frame),
fThread(thread), fThread(thread),
fCloseTarget(target), fCloseTarget(target)
fCurrentEvaluationType(B_INT64_TYPE)
{ {
fLanguage->AcquireReference(); fLanguage->AcquireReference();
@@ -52,9 +52,6 @@ ExpressionEvaluationWindow::ExpressionEvaluationWindow(
if (fThread != NULL) if (fThread != NULL)
fThread->AcquireReference(); fThread->AcquireReference();
AutoLocker< ::Team> teamLocker(fTeam);
fTeam->AddListener(this);
} }
@@ -68,18 +65,16 @@ ExpressionEvaluationWindow::~ExpressionEvaluationWindow()
if (fThread != NULL) if (fThread != NULL)
fThread->ReleaseReference(); fThread->ReleaseReference();
AutoLocker< ::Team> teamLocker(fTeam); fExpressionInfo->ReleaseReference();
fTeam->RemoveListener(this);
} }
ExpressionEvaluationWindow* ExpressionEvaluationWindow*
ExpressionEvaluationWindow::Create(::Team* team, SourceLanguage* language, ExpressionEvaluationWindow::Create(SourceLanguage* language, StackFrame* frame,
StackFrame* frame, ::Thread* thread, UserInterfaceListener* listener, ::Thread* thread, UserInterfaceListener* listener, BHandler* target)
BHandler* target)
{ {
ExpressionEvaluationWindow* self = new ExpressionEvaluationWindow(team, ExpressionEvaluationWindow* self = new ExpressionEvaluationWindow(language,
language, frame, thread, listener, target); frame, thread, listener, target);
try { try {
self->_Init(); self->_Init();
@@ -96,6 +91,10 @@ ExpressionEvaluationWindow::Create(::Team* team, SourceLanguage* language,
void void
ExpressionEvaluationWindow::_Init() ExpressionEvaluationWindow::_Init()
{ {
::Type* type = new SyntheticPrimitiveType(B_INT64_TYPE);
BReference< ::Type> typeReference(type, true);
fExpressionInfo = new ExpressionInfo(NULL, type);
fExpressionInput = new BTextControl("Expression:", NULL, fExpressionInput = new BTextControl("Expression:", NULL,
new BMessage(MSG_EVALUATE_EXPRESSION)); new BMessage(MSG_EVALUATE_EXPRESSION));
BLayoutItem* labelItem = fExpressionInput->CreateLabelLayoutItem(); BLayoutItem* labelItem = fExpressionInput->CreateLabelLayoutItem();
@@ -173,22 +172,12 @@ ExpressionEvaluationWindow::_AddMenuItemForType(BMenu* menu, type_code type)
void void
ExpressionEvaluationWindow::ExpressionEvaluated( ExpressionEvaluationWindow::ExpressionEvaluated(ExpressionInfo* info,
const Team::ExpressionEvaluationEvent& event) status_t result, Value* value)
{ {
BMessage message(MSG_EXPRESSION_EVALUATED); BMessage message(MSG_EXPRESSION_EVALUATED);
message.AddInt32("result", result);
AutoLocker<BLooper> lock(this);
if (!lock.IsLocked())
return;
if (event.GetExpression() != fExpressionInput->Text())
return;
lock.Unlock();
message.AddInt32("result", event.GetResult());
BReference<Value> reference; BReference<Value> reference;
Value* value = event.GetValue();
if (value != NULL) { if (value != NULL) {
message.AddPointer("value", value); message.AddPointer("value", value);
reference.SetTo(value); reference.SetTo(value);
@@ -226,15 +215,28 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message)
if (fExpressionInput->TextView()->TextLength() == 0) if (fExpressionInput->TextView()->TextLength() == 0)
break; break;
fExpressionInfo->SetExpression(fExpressionInput->Text());
fListener->ExpressionEvaluationRequested(fLanguage, fListener->ExpressionEvaluationRequested(fLanguage,
fExpressionInput->Text(), fCurrentEvaluationType, fStackFrame, fExpressionInfo, fStackFrame, fThread);
fThread);
break; break;
} }
case MSG_CHANGE_EVALUATION_TYPE: case MSG_CHANGE_EVALUATION_TYPE:
{ {
fCurrentEvaluationType = message->FindInt32("type"); uint32 typeConstant = message->FindInt32("type");
PrimitiveType* type = dynamic_cast<PrimitiveType*>(
fExpressionInfo->ResultType());
if (type->TypeConstant() == typeConstant)
break;
type = new(std::nothrow) SyntheticPrimitiveType(
typeConstant);
if (type == NULL)
break;
BReference< ::Type> typeReference(type, true);
fExpressionInfo->SetResultType(type);
break; break;
} }
@@ -8,26 +8,27 @@
#include <Window.h> #include <Window.h>
#include "Team.h" #include "ExpressionInfo.h"
#include "types/Types.h" #include "types/Types.h"
class BMenu; class BMenu;
class BMenuItem; class BMenuItem;
class BButton; class BButton;
class BStringView; class BStringView;
class BTextControl; class BTextControl;
class Team;
class Thread; class Thread;
class PrimitiveType;
class SourceLanguage; class SourceLanguage;
class StackFrame; class StackFrame;
class UserInterfaceListener; class UserInterfaceListener;
class ExpressionEvaluationWindow : public BWindow, private Team::Listener class ExpressionEvaluationWindow : public BWindow,
private ExpressionInfo::Listener
{ {
public: public:
ExpressionEvaluationWindow( ExpressionEvaluationWindow(
::Team* team,
SourceLanguage* language, SourceLanguage* language,
StackFrame* frame, StackFrame* frame,
::Thread* thread, ::Thread* thread,
@@ -37,7 +38,6 @@ public:
~ExpressionEvaluationWindow(); ~ExpressionEvaluationWindow();
static ExpressionEvaluationWindow* Create( static ExpressionEvaluationWindow* Create(
::Team* team,
SourceLanguage* language, SourceLanguage* language,
StackFrame* frame, StackFrame* frame,
::Thread* thread, ::Thread* thread,
@@ -57,14 +57,13 @@ private:
BMenuItem* _AddMenuItemForType(BMenu* menu, BMenuItem* _AddMenuItemForType(BMenu* menu,
type_code type); type_code type);
// Team::Listener // ExpressionInfo::Listener
virtual void ExpressionEvaluated( virtual void ExpressionEvaluated(ExpressionInfo* info,
const Team::ExpressionEvaluationEvent& status_t result, Value* value);
event);
private: private:
::Team* fTeam;
SourceLanguage* fLanguage; SourceLanguage* fLanguage;
ExpressionInfo* fExpressionInfo;
BTextControl* fExpressionInput; BTextControl* fExpressionInput;
BStringView* fExpressionOutput; BStringView* fExpressionOutput;
BButton* fEvaluateButton; BButton* fEvaluateButton;
@@ -72,7 +71,6 @@ private:
StackFrame* fStackFrame; StackFrame* fStackFrame;
::Thread* fThread; ::Thread* fThread;
BHandler* fCloseTarget; BHandler* fCloseTarget;
type_code fCurrentEvaluationType;
}; };
#endif // EXPRESSION_EVALUATION_WINDOW_H #endif // EXPRESSION_EVALUATION_WINDOW_H
@@ -362,8 +362,8 @@ TeamWindow::MessageReceived(BMessage* message)
BReference<SourceLanguage> languageReference(language, BReference<SourceLanguage> languageReference(language,
true); true);
fExpressionWindow = ExpressionEvaluationWindow::Create( fExpressionWindow = ExpressionEvaluationWindow::Create(
fTeam, language, fActiveStackFrame, fActiveThread, language, fActiveStackFrame, fActiveThread, fListener,
fListener, this); this);
if (fExpressionWindow != NULL) if (fExpressionWindow != NULL)
fExpressionWindow->Show(); fExpressionWindow->Show();
} catch (...) { } catch (...) {
@@ -488,7 +488,7 @@ TeamWindow::MessageReceived(BMessage* message)
try { try {
WatchPromptWindow* window = WatchPromptWindow::Create( WatchPromptWindow* window = WatchPromptWindow::Create(
fTeam, address, type, length, fTeam->GetArchitecture(), address, type, length,
fListener); fListener);
window->Show(); window->Show();
} catch (...) { } catch (...) {
@@ -908,16 +908,15 @@ TeamWindow::ValueNodeValueRequested(CpuState* cpuState,
void void
TeamWindow::ExpressionEvaluationRequested(const char* expression, TeamWindow::ExpressionEvaluationRequested(ExpressionInfo* info,
type_code resultType, StackFrame* frame, ::Thread* thread) StackFrame* frame, ::Thread* thread)
{ {
SourceLanguage* language; SourceLanguage* language;
if (_GetActiveSourceLanguage(language) != B_OK) if (_GetActiveSourceLanguage(language) != B_OK)
return; return;
BReference<SourceLanguage> languageReference(language, true); BReference<SourceLanguage> languageReference(language, true);
fListener->ExpressionEvaluationRequested(language, expression, resultType, fListener->ExpressionEvaluationRequested(language, info, frame, thread);
frame, thread);
} }
@@ -991,32 +990,6 @@ TeamWindow::WatchpointChanged(const Team::WatchpointEvent& event)
} }
void
TeamWindow::ExpressionEvaluated(const Team::ExpressionEvaluationEvent& event)
{
BMessage message(MSG_EXPRESSION_EVALUATED);
if (message.AddString("expression", event.GetExpression()) != B_OK
|| message.AddInt32("result", event.GetResult()) != B_OK) {
return;
}
BReference<Value> reference;
Value* value = event.GetValue();
if (value != NULL) {
if (message.AddPointer("value", value) != B_OK)
return;
reference.SetTo(value);
}
// currently, the only circumstance in which TeamWindow cares about
// expression evaluation results is when handling them on behalf of
// VariablesView. As such, simply forward them on.
BMessenger messenger(fVariablesView);
if (messenger.SendMessage(&message) == B_OK)
reference.Detach();
}
void void
TeamWindow::DebugReportChanged(const Team::DebugReportEvent& event) TeamWindow::DebugReportChanged(const Team::DebugReportEvent& event)
{ {
@@ -128,8 +128,7 @@ private:
ValueNodeContainer* container, ValueNodeContainer* container,
ValueNode* valueNode); ValueNode* valueNode);
virtual void ExpressionEvaluationRequested( virtual void ExpressionEvaluationRequested(
const char* expression, ExpressionInfo* info,
type_code resultType,
StackFrame* frame, StackFrame* frame,
::Thread* thread); ::Thread* thread);
@@ -148,9 +147,6 @@ private:
const Team::UserBreakpointEvent& event); const Team::UserBreakpointEvent& event);
virtual void WatchpointChanged( virtual void WatchpointChanged(
const Team::WatchpointEvent& event); const Team::WatchpointEvent& event);
virtual void ExpressionEvaluated(
const Team::ExpressionEvaluationEvent&
event);
virtual void DebugReportChanged( virtual void DebugReportChanged(
const Team::DebugReportEvent& event); const Team::DebugReportEvent& event);
@@ -1947,22 +1947,24 @@ VariablesView::MessageReceived(BMessage* message)
BReference<Type> typeReference(resultType, true); BReference<Type> typeReference(resultType, true);
status_t error = _AddExpression(expression, resultType); ExpressionInfo* info;
status_t error = _AddExpression(expression, resultType, info);
if (error != B_OK) { if (error != B_OK) {
// TODO: notify user of failure // TODO: notify user of failure
break; break;
} }
fListener->ExpressionEvaluationRequested(expression, type, fListener->ExpressionEvaluationRequested(info, fStackFrame,
fStackFrame, fThread); fThread);
break; break;
} }
case MSG_EXPRESSION_EVALUATED: case MSG_EXPRESSION_EVALUATED:
{ {
const char* expression; ExpressionInfo* info;
status_t result; status_t result;
Value* value = NULL; Value* value = NULL;
if (message->FindString("expression", &expression) != B_OK if (message->FindPointer("info",
reinterpret_cast<void**>(&info)) != B_OK
|| message->FindInt32("result", &result) != B_OK) { || message->FindInt32("result", &result) != B_OK) {
break; break;
} }
@@ -1973,7 +1975,7 @@ VariablesView::MessageReceived(BMessage* message)
valueReference.SetTo(value, true); valueReference.SetTo(value, true);
} }
_SetExpressionNodeValue(expression, result, value); _SetExpressionNodeValue(info, result, value);
break; break;
} }
case MSG_VALUE_NODE_CHANGED: case MSG_VALUE_NODE_CHANGED:
@@ -2220,6 +2222,25 @@ VariablesView::TreeTableCellMouseDown(TreeTable* table,
} }
void
VariablesView::ExpressionEvaluated(ExpressionInfo* info, status_t result,
Value* value)
{
BMessage message(MSG_EXPRESSION_EVALUATED);
message.AddPointer("info", info);
message.AddInt32("result", result);
BReference<Value> valueReference;
if (value != NULL) {
valueReference.SetTo(value);
message.AddPointer("value", value);
}
if (BMessenger(this).SendMessage(&message) == B_OK)
valueReference.Detach();
}
void void
VariablesView::_Init() VariablesView::_Init()
{ {
@@ -2700,7 +2721,8 @@ VariablesView::_CopyVariableValueToClipboard()
status_t status_t
VariablesView::_AddExpression(const char* expression, Type* resultType) VariablesView::_AddExpression(const char* expression, Type* resultType,
ExpressionInfo*& _info)
{ {
// if our stack frame doesn't have an associated function, // if our stack frame doesn't have an associated function,
// we can't add an expression // we can't add an expression
@@ -2734,14 +2756,16 @@ VariablesView::_AddExpression(const char* expression, Type* resultType)
BReference<ExpressionInfo> infoReference(info, true); BReference<ExpressionInfo> infoReference(info, true);
status_t error = _AddExpressionNode(*info); status_t error = _AddExpressionNode(info);
if (error != B_OK) if (error != B_OK)
return error; return error;
if (!entry->AddItem(info)) if (!entry->AddItem(info))
return B_NO_MEMORY; return B_NO_MEMORY;
info->AddListener(this);
infoReference.Detach(); infoReference.Detach();
_info = info;
return B_OK; return B_OK;
} }
@@ -2765,6 +2789,7 @@ VariablesView::_RemoveExpression(ModelNode* node)
ExpressionInfo* info = entry->ItemAt(i); ExpressionInfo* info = entry->ItemAt(i);
if (info->Expression() == child->GetExpression()) { if (info->Expression() == child->GetExpression()) {
entry->RemoveItemAt(i); entry->RemoveItemAt(i);
info->RemoveListener(this);
info->ReleaseReference(); info->ReleaseReference();
break; break;
} }
@@ -2775,11 +2800,11 @@ VariablesView::_RemoveExpression(ModelNode* node)
status_t status_t
VariablesView::_AddExpressionNode(const ExpressionInfo& info) VariablesView::_AddExpressionNode(ExpressionInfo* info)
{ {
Type* type = info.ResultType(); Type* type = info->ResultType();
ExpressionValueNodeChild* child ExpressionValueNodeChild* child
= new(std::nothrow) ExpressionValueNodeChild(info.Expression(), type); = new(std::nothrow) ExpressionValueNodeChild(info->Expression(), type);
if (child == NULL) if (child == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -2823,18 +2848,15 @@ VariablesView::_RestoreExpressionNodes()
for (int32 i = 0; i < entry->CountItems(); i++) { for (int32 i = 0; i < entry->CountItems(); i++) {
ExpressionInfo* info = entry->ItemAt(i); ExpressionInfo* info = entry->ItemAt(i);
_AddExpressionNode(*info); _AddExpressionNode(info);
SyntheticPrimitiveType* type fListener->ExpressionEvaluationRequested(info, fStackFrame, fThread);
= dynamic_cast<SyntheticPrimitiveType*>(info->ResultType());
fListener->ExpressionEvaluationRequested(info->Expression(),
type->TypeConstant(), fStackFrame, fThread);
} }
} }
void void
VariablesView::_SetExpressionNodeValue(const char* expression, VariablesView::_SetExpressionNodeValue(ExpressionInfo* info, status_t result,
status_t finalResult, Value* value) Value* value)
{ {
FunctionID* id = fStackFrame->Function()->GetFunctionID(); FunctionID* id = fStackFrame->Function()->GetFunctionID();
BReference<FunctionID> idReference(id, true); BReference<FunctionID> idReference(id, true);
@@ -2852,10 +2874,10 @@ VariablesView::_SetExpressionNodeValue(const char* expression,
if (child == NULL) if (child == NULL)
continue; continue;
if (child->GetExpression() != expression) if (child->GetExpression() != info->Expression())
continue; continue;
child->Node()->SetLocationAndValue(NULL, value, finalResult); child->Node()->SetLocationAndValue(NULL, value, result);
return; return;
} }
} }
@@ -12,10 +12,11 @@
#include "table/TreeTable.h" #include "table/TreeTable.h"
#include "ExpressionInfo.h"
class ActionMenuItem; class ActionMenuItem;
class CpuState; class CpuState;
class ExpressionInfo;
class SettingsMenu; class SettingsMenu;
class StackFrame; class StackFrame;
class Thread; class Thread;
@@ -29,7 +30,8 @@ class VariablesViewState;
class VariablesViewStateHistory; class VariablesViewStateHistory;
class VariablesView : public BGroupView, private TreeTableListener { class VariablesView : public BGroupView, private TreeTableListener,
private ExpressionInfo::Listener {
public: public:
class Listener; class Listener;
@@ -62,6 +64,10 @@ private:
int32 columnIndex, BPoint screenWhere, int32 columnIndex, BPoint screenWhere,
uint32 buttons); uint32 buttons);
// ExpressionInfo::Listener
virtual void ExpressionEvaluated(ExpressionInfo* info,
status_t result, Value* value);
private: private:
class ContainerListener; class ContainerListener;
class ModelNode; class ModelNode;
@@ -103,14 +109,15 @@ private:
void _CopyVariableValueToClipboard(); void _CopyVariableValueToClipboard();
status_t _AddExpression(const char* expression, status_t _AddExpression(const char* expression,
Type* resultType); Type* resultType,
ExpressionInfo*& _info);
void _RemoveExpression(ModelNode* node); void _RemoveExpression(ModelNode* node);
status_t _AddExpressionNode(const ExpressionInfo& info); status_t _AddExpressionNode(ExpressionInfo* info);
void _RestoreExpressionNodes(); void _RestoreExpressionNodes();
void _SetExpressionNodeValue(const char* expression, void _SetExpressionNodeValue(ExpressionInfo* info,
status_t finalResult, Value* value); status_t result, Value* value);
status_t _GetTypeForTypeCode(int32 typeCode, status_t _GetTypeForTypeCode(int32 typeCode,
Type*& _resultType) const; Type*& _resultType) const;
@@ -139,8 +146,7 @@ public:
ValueNode* valueNode) = 0; ValueNode* valueNode) = 0;
virtual void ExpressionEvaluationRequested( virtual void ExpressionEvaluationRequested(
const char* expression, ExpressionInfo* info,
type_code resultType,
StackFrame* frame, StackFrame* frame,
Thread* thread) = 0; Thread* thread) = 0;
}; };
@@ -18,53 +18,61 @@
#include "Architecture.h" #include "Architecture.h"
#include "CppLanguage.h" #include "CppLanguage.h"
#include "MessageCodes.h" #include "MessageCodes.h"
#include "Number.h" #include "SyntheticPrimitiveType.h"
#include "UserInterface.h" #include "UserInterface.h"
#include "Value.h" #include "Value.h"
#include "Watchpoint.h" #include "Watchpoint.h"
WatchPromptWindow::WatchPromptWindow(::Team* team, target_addr_t address, WatchPromptWindow::WatchPromptWindow(Architecture* architecture,
uint32 type, int32 length, UserInterfaceListener* listener) target_addr_t address, uint32 type, int32 length,
UserInterfaceListener* listener)
: :
BWindow(BRect(), "Edit Watchpoint", B_FLOATING_WINDOW, BWindow(BRect(), "Edit Watchpoint", B_FLOATING_WINDOW,
B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
fInitialAddress(address), fInitialAddress(address),
fInitialType(type), fInitialType(type),
fInitialLength(length), fInitialLength(length),
fTeam(team), fArchitecture(architecture),
fRequestedAddress(0), fRequestedAddress(0),
fRequestedLength(0), fRequestedLength(0),
fAddressInput(NULL), fAddressInput(NULL),
fLengthInput(NULL), fLengthInput(NULL),
fAddressExpressionInfo(NULL),
fLengthExpressionInfo(NULL),
fTypeField(NULL), fTypeField(NULL),
fListener(listener), fListener(listener),
fLanguage(NULL) fLanguage(NULL)
{ {
AutoLocker< ::Team> teamLocker(fTeam); fArchitecture->AcquireReference();
fTeam->AddListener(this);
fTeam->GetArchitecture()->AcquireReference();
} }
WatchPromptWindow::~WatchPromptWindow() WatchPromptWindow::~WatchPromptWindow()
{ {
fTeam->GetArchitecture()->ReleaseReference(); fArchitecture->ReleaseReference();
AutoLocker< ::Team> teamLocker(fTeam);
fTeam->RemoveListener(this);
if (fLanguage != NULL) if (fLanguage != NULL)
fLanguage->ReleaseReference(); fLanguage->ReleaseReference();
if (fAddressExpressionInfo != NULL) {
fAddressExpressionInfo->RemoveListener(this);
fAddressExpressionInfo->ReleaseReference();
}
if (fLengthExpressionInfo != NULL) {
fLengthExpressionInfo->RemoveListener(this);
fLengthExpressionInfo->ReleaseReference();
}
} }
WatchPromptWindow* WatchPromptWindow*
WatchPromptWindow::Create(::Team* team, target_addr_t address, uint32 type, WatchPromptWindow::Create(Architecture* architecture, target_addr_t address,
int32 length, UserInterfaceListener* listener) uint32 type, int32 length, UserInterfaceListener* listener)
{ {
WatchPromptWindow* self = new WatchPromptWindow(team, address, type, WatchPromptWindow* self = new WatchPromptWindow(architecture, address,
length, listener); type, length, listener);
try { try {
self->_Init(); self->_Init();
@@ -83,17 +91,27 @@ WatchPromptWindow::_Init()
{ {
fLanguage = new CppLanguage(); fLanguage = new CppLanguage();
PrimitiveType* type = new SyntheticPrimitiveType(B_UINT64_TYPE);
BReference<PrimitiveType> typeReference(type, true);
BString text; BString text;
text.SetToFormat("0x%" B_PRIx64, fInitialAddress); text.SetToFormat("0x%" B_PRIx64, fInitialAddress);
fAddressInput = new BTextControl("Address:", text, NULL); fAddressInput = new BTextControl("Address:", text, NULL);
fAddressExpressionInfo = new ExpressionInfo(text, type);
fAddressExpressionInfo->AddListener(this);
type = new SyntheticPrimitiveType(B_INT32_TYPE);
typeReference.SetTo(type, true);
text.SetToFormat("%" B_PRId32, fInitialLength); text.SetToFormat("%" B_PRId32, fInitialLength);
fLengthInput = new BTextControl("Length:", text, NULL); fLengthInput = new BTextControl("Length:", text, NULL);
fLengthExpressionInfo = new ExpressionInfo(text, type);
fLengthExpressionInfo->AddListener(this);
int32 maxDebugRegisters = 0; int32 maxDebugRegisters = 0;
int32 maxBytesPerRegister = 0; int32 maxBytesPerRegister = 0;
uint8 debugCapabilityFlags = 0; uint8 debugCapabilityFlags = 0;
fTeam->GetArchitecture()->GetWatchpointDebugCapabilities(maxDebugRegisters, fArchitecture->GetWatchpointDebugCapabilities(maxDebugRegisters,
maxBytesPerRegister, debugCapabilityFlags); maxBytesPerRegister, debugCapabilityFlags);
BMenu* typeMenu = new BMenu("Watch type"); BMenu* typeMenu = new BMenu("Watch type");
@@ -151,23 +169,11 @@ WatchPromptWindow::Show()
void void
WatchPromptWindow::ExpressionEvaluated( WatchPromptWindow::ExpressionEvaluated(ExpressionInfo* info, status_t result,
const Team::ExpressionEvaluationEvent& event) Value* value)
{ {
BMessage message(MSG_EXPRESSION_EVALUATED); BMessage message(MSG_EXPRESSION_EVALUATED);
AutoLocker<BLooper> lock(this); message.AddInt32("result", result);
if (!lock.IsLocked())
return;
BString expression = event.GetExpression();
if (expression != fAddressInput->Text()
&& expression != fLengthInput->Text()) {
return;
}
lock.Unlock();
message.AddInt32("result", event.GetResult());
Value* value = event.GetValue();
BReference<Value> reference; BReference<Value> reference;
if (value != NULL) { if (value != NULL) {
reference.SetTo(value); reference.SetTo(value);
@@ -231,11 +237,13 @@ WatchPromptWindow::MessageReceived(BMessage* message)
fRequestedAddress = 0; fRequestedAddress = 0;
fRequestedLength = 0; fRequestedLength = 0;
fAddressExpressionInfo->SetExpression(fAddressInput->Text());
fListener->ExpressionEvaluationRequested(fLanguage, fListener->ExpressionEvaluationRequested(fLanguage,
fAddressInput->Text(), B_UINT64_TYPE); fAddressExpressionInfo);
fLengthExpressionInfo->SetExpression(fLengthInput->Text());
fListener->ExpressionEvaluationRequested(fLanguage, fListener->ExpressionEvaluationRequested(fLanguage,
fLengthInput->Text(), B_INT32_TYPE); fLengthExpressionInfo);
break; break;
} }
@@ -8,10 +8,11 @@
#include <Window.h> #include <Window.h>
#include "Team.h" #include "ExpressionInfo.h"
#include "types/Types.h" #include "types/Types.h"
class Architecture;
class BMenuField; class BMenuField;
class BTextControl; class BTextControl;
class SourceLanguage; class SourceLanguage;
@@ -19,17 +20,17 @@ class Watchpoint;
class UserInterfaceListener; class UserInterfaceListener;
class WatchPromptWindow : public BWindow, private Team::Listener class WatchPromptWindow : public BWindow, private ExpressionInfo::Listener
{ {
public: public:
WatchPromptWindow(::Team* team, WatchPromptWindow(Architecture* architecture,
target_addr_t address, uint32 type, target_addr_t address, uint32 type,
int32 length, int32 length,
UserInterfaceListener* listener); UserInterfaceListener* listener);
~WatchPromptWindow(); ~WatchPromptWindow();
static WatchPromptWindow* Create(::Team* team, static WatchPromptWindow* Create(Architecture* architecture,
target_addr_t address, uint32 type, target_addr_t address, uint32 type,
int32 length, int32 length,
UserInterfaceListener* listener); UserInterfaceListener* listener);
@@ -40,10 +41,9 @@ public:
virtual void Show(); virtual void Show();
// Team::Listener // ExpressionInfo::Listener
virtual void ExpressionEvaluated( virtual void ExpressionEvaluated(ExpressionInfo* info,
const Team::ExpressionEvaluationEvent& status_t result, Value* value);
event);
private: private:
void _Init(); void _Init();
@@ -53,11 +53,13 @@ private:
target_addr_t fInitialAddress; target_addr_t fInitialAddress;
uint32 fInitialType; uint32 fInitialType;
int32 fInitialLength; int32 fInitialLength;
::Team* fTeam; Architecture* fArchitecture;
target_addr_t fRequestedAddress; target_addr_t fRequestedAddress;
int32 fRequestedLength; int32 fRequestedLength;
BTextControl* fAddressInput; BTextControl* fAddressInput;
BTextControl* fLengthInput; BTextControl* fLengthInput;
ExpressionInfo* fAddressExpressionInfo;
ExpressionInfo* fLengthExpressionInfo;
BMenuField* fTypeField; BMenuField* fTypeField;
UserInterfaceListener* fListener; UserInterfaceListener* fListener;
BButton* fWatchButton; BButton* fWatchButton;