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:
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user