Debugger: Implement expression variable value resolution.
General: - Resolving variable values requires both a stack frame and a CPU state. Adjust all interfaces and callers accordingly. ExpressionEvaluationJob: - Pass additional parameters needed for variable value resolution. - If variable resolution is desired, ExpressionEvaluationJob now creates a temporary ValueNodeManager for that purpose. - If the expression parser returns a value node pointer that needs to be resolved, schedule a corresponding job and wait. CLanguageExpressionEvaluator: - Clean up some leftovers that were preventing variable names from being handled properly in some cases. - Implement handling of identifier names. These are now looked up against the value node graph of the active node manager, and if found, corresponding values are retrieved. If the value has not yet been resolved, an exception is thrown to ask that to be done. This gets value resolution working for basic local variables and function parameters, and consequently, #9712. Structure/class members and/or pointer indirection aren't yet handled.
This commit is contained in:
@@ -732,7 +732,16 @@ TeamDebugger::MessageReceived(BMessage* message)
|
||||
frame = NULL;
|
||||
}
|
||||
|
||||
_HandleEvaluateExpression(language, expression, resultType, frame);
|
||||
::Thread* thread;
|
||||
if (message->FindPointer("thread",
|
||||
reinterpret_cast<void**>(&thread)) != B_OK) {
|
||||
// the thread isn't needed, unless variable
|
||||
// evaluation is desired.
|
||||
thread = NULL;
|
||||
}
|
||||
|
||||
_HandleEvaluateExpression(language, expression, resultType,
|
||||
frame, thread);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1087,7 +1096,8 @@ TeamDebugger::InspectRequested(target_addr_t address,
|
||||
|
||||
void
|
||||
TeamDebugger::ExpressionEvaluationRequested(SourceLanguage* language,
|
||||
const char* expression, type_code resultType, StackFrame* frame)
|
||||
const char* expression, type_code resultType, StackFrame* frame,
|
||||
::Thread* thread)
|
||||
{
|
||||
BMessage message(MSG_EVALUATE_EXPRESSION);
|
||||
message.AddPointer("language", language);
|
||||
@@ -1095,6 +1105,8 @@ TeamDebugger::ExpressionEvaluationRequested(SourceLanguage* language,
|
||||
message.AddInt32("type", resultType);
|
||||
if (frame != NULL)
|
||||
message.AddPointer("frame", frame);
|
||||
if (thread != NULL)
|
||||
message.AddPointer("thread", thread);
|
||||
|
||||
BReference<SourceLanguage> reference(language);
|
||||
if (PostMessage(&message) == B_OK)
|
||||
@@ -1982,11 +1994,12 @@ TeamDebugger::_HandleInspectAddress(target_addr_t address,
|
||||
|
||||
void
|
||||
TeamDebugger::_HandleEvaluateExpression(SourceLanguage* language,
|
||||
const char* expression, type_code resultType, StackFrame* frame)
|
||||
const char* expression, type_code resultType, StackFrame* frame,
|
||||
::Thread* thread)
|
||||
{
|
||||
status_t result = fWorker->ScheduleJob(
|
||||
new(std::nothrow) ExpressionEvaluationJob(fTeam, language,
|
||||
expression, resultType, frame));
|
||||
new(std::nothrow) ExpressionEvaluationJob(fTeam, fDebuggerInterface,
|
||||
language, expression, resultType, frame, thread));
|
||||
if (result != B_OK) {
|
||||
_NotifyUser("Evaluate Expression", "Failed to evaluate expression: %s",
|
||||
strerror(result));
|
||||
|
||||
@@ -27,6 +27,7 @@ class FileManager;
|
||||
class SettingsManager;
|
||||
class TeamDebugInfo;
|
||||
class TeamMemoryBlockManager;
|
||||
class Thread;
|
||||
class WatchpointManager;
|
||||
|
||||
|
||||
@@ -106,7 +107,8 @@ private:
|
||||
SourceLanguage* language,
|
||||
const char* expression,
|
||||
type_code resultType,
|
||||
StackFrame* frame = NULL);
|
||||
StackFrame* frame = NULL,
|
||||
::Thread* thread = NULL);
|
||||
|
||||
virtual void DebugReportRequested(entry_ref* targetPath);
|
||||
|
||||
@@ -193,7 +195,8 @@ private:
|
||||
SourceLanguage* language,
|
||||
const char* expression,
|
||||
type_code resultType,
|
||||
StackFrame* frame);
|
||||
StackFrame* frame,
|
||||
::Thread* thread);
|
||||
|
||||
status_t _HandleSetArguments(int argc,
|
||||
const char* const* argv);
|
||||
|
||||
@@ -9,26 +9,38 @@
|
||||
|
||||
#include <AutoLocker.h>
|
||||
|
||||
#include "DebuggerInterface.h"
|
||||
#include "SourceLanguage.h"
|
||||
#include "StackFrame.h"
|
||||
#include "Team.h"
|
||||
#include "Thread.h"
|
||||
#include "Value.h"
|
||||
#include "ValueNode.h"
|
||||
#include "ValueNodeManager.h"
|
||||
|
||||
|
||||
ExpressionEvaluationJob::ExpressionEvaluationJob(Team* team,
|
||||
SourceLanguage* language, const char* expression, type_code resultType,
|
||||
StackFrame* frame)
|
||||
DebuggerInterface* debuggerInterface, SourceLanguage* language,
|
||||
const char* expression, type_code resultType, StackFrame* frame,
|
||||
Thread* thread)
|
||||
:
|
||||
fKey(expression, JOB_TYPE_EVALUATE_EXPRESSION),
|
||||
fTeam(team),
|
||||
fDebuggerInterface(debuggerInterface),
|
||||
fArchitecture(debuggerInterface->GetArchitecture()),
|
||||
fTypeInformation(team->GetTeamTypeInformation()),
|
||||
fLanguage(language),
|
||||
fExpression(expression),
|
||||
fResultType(resultType),
|
||||
fFrame(frame)
|
||||
fFrame(frame),
|
||||
fThread(thread),
|
||||
fManager(NULL)
|
||||
{
|
||||
fLanguage->AcquireReference();
|
||||
if (fFrame != NULL)
|
||||
fFrame->AcquireReference();
|
||||
if (fThread != NULL)
|
||||
fThread->AcquireReference();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +49,10 @@ ExpressionEvaluationJob::~ExpressionEvaluationJob()
|
||||
fLanguage->ReleaseReference();
|
||||
if (fFrame != NULL)
|
||||
fFrame->ReleaseReference();
|
||||
if (fThread != NULL)
|
||||
fThread->ReleaseReference();
|
||||
if (fManager != NULL)
|
||||
fManager->ReleaseReference();
|
||||
}
|
||||
|
||||
|
||||
@@ -50,15 +66,80 @@ ExpressionEvaluationJob::Key() const
|
||||
status_t
|
||||
ExpressionEvaluationJob::Do()
|
||||
{
|
||||
|
||||
Value* value = NULL;
|
||||
status_t result = fLanguage->EvaluateExpression(fExpression, fResultType,
|
||||
value);
|
||||
BReference<Value> reference;
|
||||
if (value != NULL)
|
||||
reference.SetTo(value, true);
|
||||
status_t result = B_OK;
|
||||
if (fFrame != NULL && fManager == NULL) {
|
||||
fManager = new(std::nothrow) ValueNodeManager();
|
||||
if (fManager == NULL)
|
||||
result = B_NO_MEMORY;
|
||||
else
|
||||
result = fManager->SetStackFrame(fThread, fFrame);
|
||||
}
|
||||
|
||||
if (result != B_OK) {
|
||||
fTeam->NotifyExpressionEvaluated(fExpression.String(), result, NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
ValueNode* neededNode = NULL;
|
||||
result = fLanguage->EvaluateExpression(fExpression,
|
||||
fResultType, fManager, value, neededNode);
|
||||
if (neededNode != NULL) {
|
||||
result = ResolveNodeValue(neededNode);
|
||||
if (State() == JOB_STATE_WAITING)
|
||||
return B_OK;
|
||||
else if (value != NULL)
|
||||
reference.SetTo(value, true);
|
||||
// if result != B_OK, fall through
|
||||
}
|
||||
|
||||
AutoLocker<Team> teamLocker(fTeam);
|
||||
fTeam->NotifyExpressionEvaluated(fExpression.String(), result, value);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ExpressionEvaluationJob::ResolveNodeValue(ValueNode* node)
|
||||
{
|
||||
AutoLocker<Worker> workerLocker(GetWorker());
|
||||
SimpleJobKey jobKey(node, JOB_TYPE_RESOLVE_VALUE_NODE_VALUE);
|
||||
|
||||
status_t error = B_OK;
|
||||
if (GetWorker()->GetJob(jobKey) == NULL) {
|
||||
workerLocker.Unlock();
|
||||
|
||||
// schedule the job
|
||||
error = GetWorker()->ScheduleJob(
|
||||
new(std::nothrow) ResolveValueNodeValueJob(fDebuggerInterface,
|
||||
fArchitecture, fThread->GetCpuState(), fTypeInformation,
|
||||
fManager->GetContainer(), node));
|
||||
if (error != B_OK) {
|
||||
// scheduling failed -- set the value to invalid
|
||||
node->SetLocationAndValue(NULL, NULL, error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// wait for the job to finish
|
||||
workerLocker.Unlock();
|
||||
|
||||
|
||||
switch (WaitFor(jobKey)) {
|
||||
case JOB_DEPENDENCY_SUCCEEDED:
|
||||
case JOB_DEPENDENCY_NOT_FOUND:
|
||||
case JOB_DEPENDENCY_ACTIVE:
|
||||
error = B_OK;
|
||||
break;
|
||||
case JOB_DEPENDENCY_FAILED:
|
||||
case JOB_DEPENDENCY_ABORTED:
|
||||
default:
|
||||
error = B_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ class ValueLocation;
|
||||
class ValueNode;
|
||||
class ValueNodeChild;
|
||||
class ValueNodeContainer;
|
||||
class ValueNodeManager;
|
||||
class Variable;
|
||||
|
||||
|
||||
@@ -233,22 +234,32 @@ private:
|
||||
class ExpressionEvaluationJob : public Job {
|
||||
public:
|
||||
ExpressionEvaluationJob(Team* team,
|
||||
DebuggerInterface* debuggerInterface,
|
||||
SourceLanguage* language,
|
||||
const char* expression,
|
||||
type_code resultType,
|
||||
StackFrame* frame);
|
||||
StackFrame* frame,
|
||||
Thread* thread);
|
||||
virtual ~ExpressionEvaluationJob();
|
||||
|
||||
virtual const JobKey& Key() const;
|
||||
virtual status_t Do();
|
||||
|
||||
private:
|
||||
status_t ResolveNodeValue(ValueNode* node);
|
||||
|
||||
private:
|
||||
SimpleJobKey fKey;
|
||||
Team* fTeam;
|
||||
DebuggerInterface* fDebuggerInterface;
|
||||
Architecture* fArchitecture;
|
||||
TeamTypeInformation* fTypeInformation;
|
||||
SourceLanguage* fLanguage;
|
||||
BString fExpression;
|
||||
type_code fResultType;
|
||||
StackFrame* fFrame;
|
||||
Thread* fThread;
|
||||
ValueNodeManager* fManager;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -167,14 +167,15 @@ CLanguageFamily::ParseTypeExpression(const BString& expression,
|
||||
|
||||
|
||||
status_t
|
||||
CLanguageFamily::EvaluateExpression(const BString& expression,
|
||||
type_code type, Value*& _output)
|
||||
CLanguageFamily::EvaluateExpression(const BString& expression, type_code type,
|
||||
ValueNodeManager* manager, Value*& _output, ValueNode*& _neededNode)
|
||||
{
|
||||
_output = NULL;
|
||||
_neededNode = NULL;
|
||||
CLanguageExpressionEvaluator evaluator;
|
||||
Number result;
|
||||
try {
|
||||
result = evaluator.Evaluate(expression, type);
|
||||
result = evaluator.Evaluate(expression, type, manager);
|
||||
BVariant resultValue = result.GetValue();
|
||||
switch (type) {
|
||||
case B_INT8_TYPE:
|
||||
@@ -207,6 +208,8 @@ CLanguageFamily::EvaluateExpression(const BString& expression,
|
||||
ex.position, ex.message.String());
|
||||
_output = new(std::nothrow) StringValue(stringValue);
|
||||
return B_BAD_DATA;
|
||||
} catch (ValueNeededException ex) {
|
||||
_neededNode = ex.value;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
@@ -22,7 +22,8 @@ public:
|
||||
Type*& _resultType) const;
|
||||
|
||||
virtual status_t EvaluateExpression(const BString& expression,
|
||||
type_code type, Value*& _output);
|
||||
type_code type, ValueNodeManager* manager,
|
||||
Value*& _output, ValueNode*& _neededNode);
|
||||
|
||||
protected:
|
||||
virtual bool IsModifierValid(char modifier) const = 0;
|
||||
|
||||
@@ -30,7 +30,8 @@ SourceLanguage::ParseTypeExpression(const BString& expression,
|
||||
|
||||
status_t
|
||||
SourceLanguage::EvaluateExpression(const BString& expression,
|
||||
type_code type, Value*& _resultValue)
|
||||
type_code type, ValueNodeManager* manager, Value*& _resultValue,
|
||||
ValueNode*& _neededNode)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ class SyntaxHighlighter;
|
||||
class TeamTypeInformation;
|
||||
class Type;
|
||||
class Value;
|
||||
class ValueNode;
|
||||
class ValueNodeManager;
|
||||
|
||||
|
||||
class SourceLanguage : public BReferenceable {
|
||||
@@ -32,7 +34,8 @@ public:
|
||||
Type*& _resultType) const;
|
||||
|
||||
virtual status_t EvaluateExpression(const BString& expression,
|
||||
type_code type, Value*& _output);
|
||||
type_code type, ValueNodeManager* manager,
|
||||
Value*& _output, ValueNode*& _neededNode);
|
||||
};
|
||||
|
||||
|
||||
|
||||
+65
-28
@@ -11,13 +11,21 @@
|
||||
|
||||
#include "CLanguageExpressionEvaluator.h"
|
||||
|
||||
#include "Number.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "AutoLocker.h"
|
||||
|
||||
#include "Number.h"
|
||||
#include "StackFrame.h"
|
||||
#include "Thread.h"
|
||||
#include "Value.h"
|
||||
#include "ValueNode.h"
|
||||
#include "ValueNodeManager.h"
|
||||
#include "Variable.h"
|
||||
|
||||
|
||||
enum {
|
||||
TOKEN_NONE = 0,
|
||||
@@ -299,7 +307,7 @@ class CLanguageExpressionEvaluator::Tokenizer {
|
||||
fCurrentToken = Token(begin, length, _CurrentPos() - length,
|
||||
TOKEN_CONSTANT);
|
||||
fCurrentToken.value.SetTo(fType, temp.String());
|
||||
} else if (isalpha(*fCurrentChar) && *fCurrentChar != 'x') {
|
||||
} else if (isalpha(*fCurrentChar)) {
|
||||
const char* begin = fCurrentChar;
|
||||
while (*fCurrentChar != 0 && (isalpha(*fCurrentChar)
|
||||
|| isdigit(*fCurrentChar))) {
|
||||
@@ -308,10 +316,6 @@ class CLanguageExpressionEvaluator::Tokenizer {
|
||||
int32 length = fCurrentChar - begin;
|
||||
fCurrentToken = Token(begin, length, _CurrentPos() - length,
|
||||
TOKEN_IDENTIFIER);
|
||||
} else if (strncmp(fCurrentChar, "π", 2) == 0) {
|
||||
fCurrentToken = Token(fCurrentChar, 2, _CurrentPos() - 1,
|
||||
TOKEN_IDENTIFIER);
|
||||
fCurrentChar += 2;
|
||||
} else {
|
||||
if (!_ParseOperator()) {
|
||||
int32 type = TOKEN_NONE;
|
||||
@@ -517,7 +521,8 @@ class CLanguageExpressionEvaluator::Tokenizer {
|
||||
CLanguageExpressionEvaluator::CLanguageExpressionEvaluator()
|
||||
:
|
||||
fTokenizer(new Tokenizer()),
|
||||
fCurrentType(B_INT64_TYPE)
|
||||
fCurrentType(B_INT64_TYPE),
|
||||
fNodeManager(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -530,10 +535,10 @@ CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator()
|
||||
|
||||
Number
|
||||
CLanguageExpressionEvaluator::Evaluate(const char* expressionString,
|
||||
type_code type)
|
||||
type_code type, ValueNodeManager* manager)
|
||||
{
|
||||
fCurrentType = type;
|
||||
|
||||
fNodeManager = manager;
|
||||
fTokenizer->SetType(type);
|
||||
fTokenizer->SetTo(expressionString);
|
||||
|
||||
@@ -745,6 +750,7 @@ CLanguageExpressionEvaluator::_ParseUnary()
|
||||
return Number((int32)(_ParseUnary() == Number(BVariant(0L))));
|
||||
|
||||
case TOKEN_IDENTIFIER:
|
||||
fTokenizer->RewindToken();
|
||||
return _ParseIdentifier();
|
||||
|
||||
default:
|
||||
@@ -756,32 +762,63 @@ CLanguageExpressionEvaluator::_ParseUnary()
|
||||
}
|
||||
|
||||
|
||||
struct Function {
|
||||
const char* name;
|
||||
int argumentCount;
|
||||
void* function;
|
||||
Number value;
|
||||
};
|
||||
|
||||
|
||||
Number
|
||||
CLanguageExpressionEvaluator::_ParseIdentifier()
|
||||
{
|
||||
throw ParseException("Identifiers not implemented", 0);
|
||||
Token token = fTokenizer->NextToken();
|
||||
Number value;
|
||||
|
||||
return Number();
|
||||
}
|
||||
if (fNodeManager == NULL) {
|
||||
throw ParseException("Identifiers not resolvable without manager.",
|
||||
token.position);
|
||||
}
|
||||
|
||||
const BString& identifierName = token.string;
|
||||
|
||||
void
|
||||
CLanguageExpressionEvaluator::_InitArguments(Number values[], int32 argumentCount)
|
||||
{
|
||||
_EatToken(TOKEN_OPENING_BRACKET);
|
||||
ValueNodeContainer* container = fNodeManager->GetContainer();
|
||||
AutoLocker<ValueNodeContainer> containerLocker(container);
|
||||
|
||||
for (int32 i = 0; i < argumentCount; i++)
|
||||
values[i] = _ParseBinary();
|
||||
ValueNodeChild* child = NULL;
|
||||
for (int32 i = 0; i < container->CountChildren(); i++) {
|
||||
ValueNodeChild* current = container->ChildAt(i);
|
||||
if (current->Name() == identifierName) {
|
||||
child = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_EatToken(TOKEN_CLOSING_BRACKET);
|
||||
BString errorMessage;
|
||||
if (child == NULL) {
|
||||
errorMessage.SetToFormat("Unable to resolve variable name: '%s'",
|
||||
identifierName.String());
|
||||
throw ParseException(errorMessage, token.position);
|
||||
}
|
||||
|
||||
status_t state = child->LocationResolutionState();
|
||||
if (state != B_OK) {
|
||||
errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
|
||||
"%s", identifierName.String(),
|
||||
strerror(state));
|
||||
throw ParseException(errorMessage, token.position);
|
||||
}
|
||||
|
||||
ValueNode* node = child->Node();
|
||||
state = node->LocationAndValueResolutionState();
|
||||
if (state == VALUE_NODE_UNRESOLVED) {
|
||||
throw ValueNeededException(node);
|
||||
} else if (state != B_OK) {
|
||||
errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
|
||||
"%s", identifierName.String(),
|
||||
strerror(state));
|
||||
throw ParseException(errorMessage, token.position);
|
||||
}
|
||||
|
||||
BVariant variant;
|
||||
Value* nodeValue = node->GetValue();
|
||||
nodeValue->ToVariant(variant);
|
||||
value.SetTo(variant);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+19
-4
@@ -15,6 +15,10 @@
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class ValueNode;
|
||||
class ValueNodeManager;
|
||||
|
||||
|
||||
class ParseException {
|
||||
public:
|
||||
ParseException(const char* message, int32 position)
|
||||
@@ -33,9 +37,21 @@ class ParseException {
|
||||
int32 position;
|
||||
};
|
||||
|
||||
struct Function;
|
||||
class ValueNeededException {
|
||||
public:
|
||||
ValueNeededException(ValueNode* node)
|
||||
:
|
||||
value(node)
|
||||
{
|
||||
}
|
||||
|
||||
ValueNode* value;
|
||||
};
|
||||
|
||||
|
||||
class Number;
|
||||
|
||||
|
||||
class CLanguageExpressionEvaluator {
|
||||
|
||||
public:
|
||||
@@ -43,7 +59,7 @@ class CLanguageExpressionEvaluator {
|
||||
~CLanguageExpressionEvaluator();
|
||||
|
||||
Number Evaluate(const char* expressionString,
|
||||
type_code type);
|
||||
type_code type, ValueNodeManager* manager);
|
||||
|
||||
private:
|
||||
struct Token;
|
||||
@@ -56,14 +72,13 @@ class CLanguageExpressionEvaluator {
|
||||
Number _ParsePower();
|
||||
Number _ParseUnary();
|
||||
Number _ParseIdentifier();
|
||||
void _InitArguments(Number values[],
|
||||
int32 argumentCount);
|
||||
Number _ParseAtom();
|
||||
|
||||
void _EatToken(int32 type);
|
||||
|
||||
Tokenizer* fTokenizer;
|
||||
type_code fCurrentType;
|
||||
ValueNodeManager* fNodeManager;
|
||||
};
|
||||
|
||||
#endif // C_LANGUAGE_EXPRESSION_EVALUATOR_H
|
||||
|
||||
@@ -141,7 +141,8 @@ public:
|
||||
SourceLanguage* language,
|
||||
const char* expression,
|
||||
type_code resultType,
|
||||
StackFrame* frame = NULL) = 0;
|
||||
StackFrame* frame = NULL,
|
||||
Thread* thread = NULL) = 0;
|
||||
|
||||
virtual void DebugReportRequested(entry_ref* path) = 0;
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#include "MessageCodes.h"
|
||||
#include "SourceLanguage.h"
|
||||
#include "StackFrame.h"
|
||||
#include "Thread.h"
|
||||
#include "UserInterface.h"
|
||||
#include "Value.h"
|
||||
|
||||
@@ -26,8 +28,8 @@ enum {
|
||||
|
||||
|
||||
ExpressionEvaluationWindow::ExpressionEvaluationWindow(
|
||||
::Team* team, SourceLanguage* language, UserInterfaceListener* listener,
|
||||
BHandler* target)
|
||||
::Team* team, 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),
|
||||
@@ -37,11 +39,19 @@ ExpressionEvaluationWindow::ExpressionEvaluationWindow(
|
||||
fExpressionOutput(NULL),
|
||||
fEvaluateButton(NULL),
|
||||
fListener(listener),
|
||||
fStackFrame(frame),
|
||||
fThread(thread),
|
||||
fCloseTarget(target),
|
||||
fCurrentEvaluationType(B_INT64_TYPE)
|
||||
{
|
||||
fLanguage->AcquireReference();
|
||||
|
||||
if (fStackFrame != NULL)
|
||||
fStackFrame->AcquireReference();
|
||||
|
||||
if (fThread != NULL)
|
||||
fThread->AcquireReference();
|
||||
|
||||
AutoLocker< ::Team> teamLocker(fTeam);
|
||||
fTeam->AddListener(this);
|
||||
}
|
||||
@@ -51,6 +61,12 @@ ExpressionEvaluationWindow::~ExpressionEvaluationWindow()
|
||||
{
|
||||
fLanguage->ReleaseReference();
|
||||
|
||||
if (fStackFrame != NULL)
|
||||
fStackFrame->ReleaseReference();
|
||||
|
||||
if (fThread != NULL)
|
||||
fThread->ReleaseReference();
|
||||
|
||||
AutoLocker< ::Team> teamLocker(fTeam);
|
||||
fTeam->RemoveListener(this);
|
||||
}
|
||||
@@ -58,10 +74,11 @@ ExpressionEvaluationWindow::~ExpressionEvaluationWindow()
|
||||
|
||||
ExpressionEvaluationWindow*
|
||||
ExpressionEvaluationWindow::Create(::Team* team, SourceLanguage* language,
|
||||
UserInterfaceListener* listener, BHandler* target)
|
||||
StackFrame* frame, ::Thread* thread, UserInterfaceListener* listener,
|
||||
BHandler* target)
|
||||
{
|
||||
ExpressionEvaluationWindow* self = new ExpressionEvaluationWindow(team,
|
||||
language, listener, target);
|
||||
language, frame, thread, listener, target);
|
||||
|
||||
try {
|
||||
self->_Init();
|
||||
@@ -216,7 +233,8 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message)
|
||||
break;
|
||||
|
||||
fListener->ExpressionEvaluationRequested(fLanguage,
|
||||
fExpressionInput->Text(), fCurrentEvaluationType);
|
||||
fExpressionInput->Text(), fCurrentEvaluationType, fStackFrame,
|
||||
fThread);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@ class BButton;
|
||||
class BStringView;
|
||||
class BTextControl;
|
||||
class Team;
|
||||
class Thread;
|
||||
class SourceLanguage;
|
||||
class StackFrame;
|
||||
class UserInterfaceListener;
|
||||
|
||||
|
||||
@@ -26,6 +28,8 @@ public:
|
||||
ExpressionEvaluationWindow(
|
||||
::Team* team,
|
||||
SourceLanguage* language,
|
||||
StackFrame* frame,
|
||||
::Thread* thread,
|
||||
UserInterfaceListener* listener,
|
||||
BHandler* target);
|
||||
|
||||
@@ -34,6 +38,8 @@ public:
|
||||
static ExpressionEvaluationWindow* Create(
|
||||
::Team* team,
|
||||
SourceLanguage* language,
|
||||
StackFrame* frame,
|
||||
::Thread* thread,
|
||||
UserInterfaceListener* listener,
|
||||
BHandler* target);
|
||||
// throws
|
||||
@@ -60,6 +66,8 @@ private:
|
||||
BStringView* fExpressionOutput;
|
||||
BButton* fEvaluateButton;
|
||||
UserInterfaceListener* fListener;
|
||||
StackFrame* fStackFrame;
|
||||
::Thread* fThread;
|
||||
BHandler* fCloseTarget;
|
||||
type_code fCurrentEvaluationType;
|
||||
};
|
||||
|
||||
@@ -356,7 +356,8 @@ TeamWindow::MessageReceived(BMessage* message)
|
||||
BReference<SourceLanguage> languageReference(language,
|
||||
true);
|
||||
fExpressionWindow = ExpressionEvaluationWindow::Create(
|
||||
fTeam, language, fListener, this);
|
||||
fTeam, language, fActiveStackFrame, fActiveThread,
|
||||
fListener, this);
|
||||
if (fExpressionWindow != NULL)
|
||||
fExpressionWindow->Show();
|
||||
} catch (...) {
|
||||
|
||||
Reference in New Issue
Block a user