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