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:
Rene Gollent
2014-10-29 17:41:54 -04:00
parent de6278fec1
commit c3f81329bb
14 changed files with 256 additions and 60 deletions
+18 -5
View File
@@ -732,7 +732,16 @@ TeamDebugger::MessageReceived(BMessage* message)
frame = NULL; 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; break;
} }
@@ -1087,7 +1096,8 @@ TeamDebugger::InspectRequested(target_addr_t address,
void void
TeamDebugger::ExpressionEvaluationRequested(SourceLanguage* language, 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); BMessage message(MSG_EVALUATE_EXPRESSION);
message.AddPointer("language", language); message.AddPointer("language", language);
@@ -1095,6 +1105,8 @@ TeamDebugger::ExpressionEvaluationRequested(SourceLanguage* language,
message.AddInt32("type", resultType); message.AddInt32("type", resultType);
if (frame != NULL) if (frame != NULL)
message.AddPointer("frame", frame); message.AddPointer("frame", frame);
if (thread != NULL)
message.AddPointer("thread", thread);
BReference<SourceLanguage> reference(language); BReference<SourceLanguage> reference(language);
if (PostMessage(&message) == B_OK) if (PostMessage(&message) == B_OK)
@@ -1982,11 +1994,12 @@ TeamDebugger::_HandleInspectAddress(target_addr_t address,
void void
TeamDebugger::_HandleEvaluateExpression(SourceLanguage* language, 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( status_t result = fWorker->ScheduleJob(
new(std::nothrow) ExpressionEvaluationJob(fTeam, language, new(std::nothrow) ExpressionEvaluationJob(fTeam, fDebuggerInterface,
expression, resultType, frame)); language, expression, resultType, frame, thread));
if (result != B_OK) { if (result != B_OK) {
_NotifyUser("Evaluate Expression", "Failed to evaluate expression: %s", _NotifyUser("Evaluate Expression", "Failed to evaluate expression: %s",
strerror(result)); strerror(result));
+5 -2
View File
@@ -27,6 +27,7 @@ class FileManager;
class SettingsManager; class SettingsManager;
class TeamDebugInfo; class TeamDebugInfo;
class TeamMemoryBlockManager; class TeamMemoryBlockManager;
class Thread;
class WatchpointManager; class WatchpointManager;
@@ -106,7 +107,8 @@ private:
SourceLanguage* language, SourceLanguage* language,
const char* expression, const char* expression,
type_code resultType, type_code resultType,
StackFrame* frame = NULL); StackFrame* frame = NULL,
::Thread* thread = NULL);
virtual void DebugReportRequested(entry_ref* targetPath); virtual void DebugReportRequested(entry_ref* targetPath);
@@ -193,7 +195,8 @@ private:
SourceLanguage* language, SourceLanguage* language,
const char* expression, const char* expression,
type_code resultType, type_code resultType,
StackFrame* frame); StackFrame* frame,
::Thread* thread);
status_t _HandleSetArguments(int argc, status_t _HandleSetArguments(int argc,
const char* const* argv); const char* const* argv);
@@ -9,26 +9,38 @@
#include <AutoLocker.h> #include <AutoLocker.h>
#include "DebuggerInterface.h"
#include "SourceLanguage.h" #include "SourceLanguage.h"
#include "StackFrame.h" #include "StackFrame.h"
#include "Team.h" #include "Team.h"
#include "Thread.h"
#include "Value.h" #include "Value.h"
#include "ValueNode.h"
#include "ValueNodeManager.h"
ExpressionEvaluationJob::ExpressionEvaluationJob(Team* team, ExpressionEvaluationJob::ExpressionEvaluationJob(Team* team,
SourceLanguage* language, const char* expression, type_code resultType, DebuggerInterface* debuggerInterface, SourceLanguage* language,
StackFrame* frame) const char* expression, type_code resultType, StackFrame* frame,
Thread* thread)
: :
fKey(expression, JOB_TYPE_EVALUATE_EXPRESSION), fKey(expression, JOB_TYPE_EVALUATE_EXPRESSION),
fTeam(team), fTeam(team),
fDebuggerInterface(debuggerInterface),
fArchitecture(debuggerInterface->GetArchitecture()),
fTypeInformation(team->GetTeamTypeInformation()),
fLanguage(language), fLanguage(language),
fExpression(expression), fExpression(expression),
fResultType(resultType), fResultType(resultType),
fFrame(frame) fFrame(frame),
fThread(thread),
fManager(NULL)
{ {
fLanguage->AcquireReference(); fLanguage->AcquireReference();
if (fFrame != NULL) if (fFrame != NULL)
fFrame->AcquireReference(); fFrame->AcquireReference();
if (fThread != NULL)
fThread->AcquireReference();
} }
@@ -37,6 +49,10 @@ ExpressionEvaluationJob::~ExpressionEvaluationJob()
fLanguage->ReleaseReference(); fLanguage->ReleaseReference();
if (fFrame != NULL) if (fFrame != NULL)
fFrame->ReleaseReference(); fFrame->ReleaseReference();
if (fThread != NULL)
fThread->ReleaseReference();
if (fManager != NULL)
fManager->ReleaseReference();
} }
@@ -50,15 +66,80 @@ ExpressionEvaluationJob::Key() const
status_t status_t
ExpressionEvaluationJob::Do() ExpressionEvaluationJob::Do()
{ {
Value* value = NULL; Value* value = NULL;
status_t result = fLanguage->EvaluateExpression(fExpression, fResultType,
value);
BReference<Value> reference; BReference<Value> reference;
if (value != NULL) status_t result = B_OK;
reference.SetTo(value, true); 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); AutoLocker<Team> teamLocker(fTeam);
fTeam->NotifyExpressionEvaluated(fExpression.String(), result, value); fTeam->NotifyExpressionEvaluated(fExpression.String(), result, value);
return B_OK; 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;
}
+12 -1
View File
@@ -36,6 +36,7 @@ class ValueLocation;
class ValueNode; class ValueNode;
class ValueNodeChild; class ValueNodeChild;
class ValueNodeContainer; class ValueNodeContainer;
class ValueNodeManager;
class Variable; class Variable;
@@ -233,22 +234,32 @@ private:
class ExpressionEvaluationJob : public Job { class ExpressionEvaluationJob : public Job {
public: public:
ExpressionEvaluationJob(Team* team, ExpressionEvaluationJob(Team* team,
DebuggerInterface* debuggerInterface,
SourceLanguage* language, SourceLanguage* language,
const char* expression, const char* expression,
type_code resultType, type_code resultType,
StackFrame* frame); StackFrame* frame,
Thread* thread);
virtual ~ExpressionEvaluationJob(); virtual ~ExpressionEvaluationJob();
virtual const JobKey& Key() const; virtual const JobKey& Key() const;
virtual status_t Do(); virtual status_t Do();
private:
status_t ResolveNodeValue(ValueNode* node);
private: private:
SimpleJobKey fKey; SimpleJobKey fKey;
Team* fTeam; Team* fTeam;
DebuggerInterface* fDebuggerInterface;
Architecture* fArchitecture;
TeamTypeInformation* fTypeInformation;
SourceLanguage* fLanguage; SourceLanguage* fLanguage;
BString fExpression; BString fExpression;
type_code fResultType; type_code fResultType;
StackFrame* fFrame; StackFrame* fFrame;
Thread* fThread;
ValueNodeManager* fManager;
}; };
@@ -167,14 +167,15 @@ CLanguageFamily::ParseTypeExpression(const BString& expression,
status_t status_t
CLanguageFamily::EvaluateExpression(const BString& expression, CLanguageFamily::EvaluateExpression(const BString& expression, type_code type,
type_code type, Value*& _output) ValueNodeManager* manager, Value*& _output, ValueNode*& _neededNode)
{ {
_output = NULL; _output = NULL;
_neededNode = NULL;
CLanguageExpressionEvaluator evaluator; CLanguageExpressionEvaluator evaluator;
Number result; Number result;
try { try {
result = evaluator.Evaluate(expression, type); result = evaluator.Evaluate(expression, type, manager);
BVariant resultValue = result.GetValue(); BVariant resultValue = result.GetValue();
switch (type) { switch (type) {
case B_INT8_TYPE: case B_INT8_TYPE:
@@ -207,6 +208,8 @@ CLanguageFamily::EvaluateExpression(const BString& expression,
ex.position, ex.message.String()); ex.position, ex.message.String());
_output = new(std::nothrow) StringValue(stringValue); _output = new(std::nothrow) StringValue(stringValue);
return B_BAD_DATA; return B_BAD_DATA;
} catch (ValueNeededException ex) {
_neededNode = ex.value;
} }
return B_OK; return B_OK;
@@ -22,7 +22,8 @@ public:
Type*& _resultType) const; Type*& _resultType) const;
virtual status_t EvaluateExpression(const BString& expression, virtual status_t EvaluateExpression(const BString& expression,
type_code type, Value*& _output); type_code type, ValueNodeManager* manager,
Value*& _output, ValueNode*& _neededNode);
protected: protected:
virtual bool IsModifierValid(char modifier) const = 0; virtual bool IsModifierValid(char modifier) const = 0;
@@ -30,7 +30,8 @@ SourceLanguage::ParseTypeExpression(const BString& expression,
status_t status_t
SourceLanguage::EvaluateExpression(const BString& expression, SourceLanguage::EvaluateExpression(const BString& expression,
type_code type, Value*& _resultValue) type_code type, ValueNodeManager* manager, Value*& _resultValue,
ValueNode*& _neededNode)
{ {
return B_NOT_SUPPORTED; return B_NOT_SUPPORTED;
} }
@@ -15,6 +15,8 @@ class SyntaxHighlighter;
class TeamTypeInformation; class TeamTypeInformation;
class Type; class Type;
class Value; class Value;
class ValueNode;
class ValueNodeManager;
class SourceLanguage : public BReferenceable { class SourceLanguage : public BReferenceable {
@@ -32,7 +34,8 @@ public:
Type*& _resultType) const; Type*& _resultType) const;
virtual status_t EvaluateExpression(const BString& expression, virtual status_t EvaluateExpression(const BString& expression,
type_code type, Value*& _output); type_code type, ValueNodeManager* manager,
Value*& _output, ValueNode*& _neededNode);
}; };
@@ -11,13 +11,21 @@
#include "CLanguageExpressionEvaluator.h" #include "CLanguageExpressionEvaluator.h"
#include "Number.h"
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <strings.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 { enum {
TOKEN_NONE = 0, TOKEN_NONE = 0,
@@ -299,7 +307,7 @@ class CLanguageExpressionEvaluator::Tokenizer {
fCurrentToken = Token(begin, length, _CurrentPos() - length, fCurrentToken = Token(begin, length, _CurrentPos() - length,
TOKEN_CONSTANT); TOKEN_CONSTANT);
fCurrentToken.value.SetTo(fType, temp.String()); fCurrentToken.value.SetTo(fType, temp.String());
} else if (isalpha(*fCurrentChar) && *fCurrentChar != 'x') { } else if (isalpha(*fCurrentChar)) {
const char* begin = fCurrentChar; const char* begin = fCurrentChar;
while (*fCurrentChar != 0 && (isalpha(*fCurrentChar) while (*fCurrentChar != 0 && (isalpha(*fCurrentChar)
|| isdigit(*fCurrentChar))) { || isdigit(*fCurrentChar))) {
@@ -308,10 +316,6 @@ class CLanguageExpressionEvaluator::Tokenizer {
int32 length = fCurrentChar - begin; int32 length = fCurrentChar - begin;
fCurrentToken = Token(begin, length, _CurrentPos() - length, fCurrentToken = Token(begin, length, _CurrentPos() - length,
TOKEN_IDENTIFIER); TOKEN_IDENTIFIER);
} else if (strncmp(fCurrentChar, "π", 2) == 0) {
fCurrentToken = Token(fCurrentChar, 2, _CurrentPos() - 1,
TOKEN_IDENTIFIER);
fCurrentChar += 2;
} else { } else {
if (!_ParseOperator()) { if (!_ParseOperator()) {
int32 type = TOKEN_NONE; int32 type = TOKEN_NONE;
@@ -517,7 +521,8 @@ class CLanguageExpressionEvaluator::Tokenizer {
CLanguageExpressionEvaluator::CLanguageExpressionEvaluator() CLanguageExpressionEvaluator::CLanguageExpressionEvaluator()
: :
fTokenizer(new Tokenizer()), fTokenizer(new Tokenizer()),
fCurrentType(B_INT64_TYPE) fCurrentType(B_INT64_TYPE),
fNodeManager(NULL)
{ {
} }
@@ -530,10 +535,10 @@ CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator()
Number Number
CLanguageExpressionEvaluator::Evaluate(const char* expressionString, CLanguageExpressionEvaluator::Evaluate(const char* expressionString,
type_code type) type_code type, ValueNodeManager* manager)
{ {
fCurrentType = type; fCurrentType = type;
fNodeManager = manager;
fTokenizer->SetType(type); fTokenizer->SetType(type);
fTokenizer->SetTo(expressionString); fTokenizer->SetTo(expressionString);
@@ -745,6 +750,7 @@ CLanguageExpressionEvaluator::_ParseUnary()
return Number((int32)(_ParseUnary() == Number(BVariant(0L)))); return Number((int32)(_ParseUnary() == Number(BVariant(0L))));
case TOKEN_IDENTIFIER: case TOKEN_IDENTIFIER:
fTokenizer->RewindToken();
return _ParseIdentifier(); return _ParseIdentifier();
default: default:
@@ -756,32 +762,63 @@ CLanguageExpressionEvaluator::_ParseUnary()
} }
struct Function {
const char* name;
int argumentCount;
void* function;
Number value;
};
Number Number
CLanguageExpressionEvaluator::_ParseIdentifier() 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 ValueNodeContainer* container = fNodeManager->GetContainer();
CLanguageExpressionEvaluator::_InitArguments(Number values[], int32 argumentCount) AutoLocker<ValueNodeContainer> containerLocker(container);
{
_EatToken(TOKEN_OPENING_BRACKET);
for (int32 i = 0; i < argumentCount; i++) ValueNodeChild* child = NULL;
values[i] = _ParseBinary(); 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;
} }
@@ -15,6 +15,10 @@
#include <String.h> #include <String.h>
class ValueNode;
class ValueNodeManager;
class ParseException { class ParseException {
public: public:
ParseException(const char* message, int32 position) ParseException(const char* message, int32 position)
@@ -33,9 +37,21 @@ class ParseException {
int32 position; int32 position;
}; };
struct Function; class ValueNeededException {
public:
ValueNeededException(ValueNode* node)
:
value(node)
{
}
ValueNode* value;
};
class Number; class Number;
class CLanguageExpressionEvaluator { class CLanguageExpressionEvaluator {
public: public:
@@ -43,7 +59,7 @@ class CLanguageExpressionEvaluator {
~CLanguageExpressionEvaluator(); ~CLanguageExpressionEvaluator();
Number Evaluate(const char* expressionString, Number Evaluate(const char* expressionString,
type_code type); type_code type, ValueNodeManager* manager);
private: private:
struct Token; struct Token;
@@ -56,14 +72,13 @@ class CLanguageExpressionEvaluator {
Number _ParsePower(); Number _ParsePower();
Number _ParseUnary(); Number _ParseUnary();
Number _ParseIdentifier(); Number _ParseIdentifier();
void _InitArguments(Number values[],
int32 argumentCount);
Number _ParseAtom(); Number _ParseAtom();
void _EatToken(int32 type); void _EatToken(int32 type);
Tokenizer* fTokenizer; Tokenizer* fTokenizer;
type_code fCurrentType; type_code fCurrentType;
ValueNodeManager* fNodeManager;
}; };
#endif // C_LANGUAGE_EXPRESSION_EVALUATOR_H #endif // C_LANGUAGE_EXPRESSION_EVALUATOR_H
@@ -141,7 +141,8 @@ public:
SourceLanguage* language, SourceLanguage* language,
const char* expression, const char* expression,
type_code resultType, type_code resultType,
StackFrame* frame = NULL) = 0; StackFrame* frame = NULL,
Thread* thread = NULL) = 0;
virtual void DebugReportRequested(entry_ref* path) = 0; virtual void DebugReportRequested(entry_ref* path) = 0;
@@ -16,6 +16,8 @@
#include "MessageCodes.h" #include "MessageCodes.h"
#include "SourceLanguage.h" #include "SourceLanguage.h"
#include "StackFrame.h"
#include "Thread.h"
#include "UserInterface.h" #include "UserInterface.h"
#include "Value.h" #include "Value.h"
@@ -26,8 +28,8 @@ enum {
ExpressionEvaluationWindow::ExpressionEvaluationWindow( ExpressionEvaluationWindow::ExpressionEvaluationWindow(
::Team* team, SourceLanguage* language, UserInterfaceListener* listener, ::Team* team, SourceLanguage* language, StackFrame* frame,
BHandler* target) ::Thread* thread, UserInterfaceListener* listener, BHandler* target)
: :
BWindow(BRect(), "Evaluate Expression", B_FLOATING_WINDOW, BWindow(BRect(), "Evaluate Expression", B_FLOATING_WINDOW,
B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
@@ -37,11 +39,19 @@ ExpressionEvaluationWindow::ExpressionEvaluationWindow(
fExpressionOutput(NULL), fExpressionOutput(NULL),
fEvaluateButton(NULL), fEvaluateButton(NULL),
fListener(listener), fListener(listener),
fStackFrame(frame),
fThread(thread),
fCloseTarget(target), fCloseTarget(target),
fCurrentEvaluationType(B_INT64_TYPE) fCurrentEvaluationType(B_INT64_TYPE)
{ {
fLanguage->AcquireReference(); fLanguage->AcquireReference();
if (fStackFrame != NULL)
fStackFrame->AcquireReference();
if (fThread != NULL)
fThread->AcquireReference();
AutoLocker< ::Team> teamLocker(fTeam); AutoLocker< ::Team> teamLocker(fTeam);
fTeam->AddListener(this); fTeam->AddListener(this);
} }
@@ -51,6 +61,12 @@ ExpressionEvaluationWindow::~ExpressionEvaluationWindow()
{ {
fLanguage->ReleaseReference(); fLanguage->ReleaseReference();
if (fStackFrame != NULL)
fStackFrame->ReleaseReference();
if (fThread != NULL)
fThread->ReleaseReference();
AutoLocker< ::Team> teamLocker(fTeam); AutoLocker< ::Team> teamLocker(fTeam);
fTeam->RemoveListener(this); fTeam->RemoveListener(this);
} }
@@ -58,10 +74,11 @@ ExpressionEvaluationWindow::~ExpressionEvaluationWindow()
ExpressionEvaluationWindow* ExpressionEvaluationWindow*
ExpressionEvaluationWindow::Create(::Team* team, SourceLanguage* language, ExpressionEvaluationWindow::Create(::Team* team, SourceLanguage* language,
UserInterfaceListener* listener, BHandler* target) StackFrame* frame, ::Thread* thread, UserInterfaceListener* listener,
BHandler* target)
{ {
ExpressionEvaluationWindow* self = new ExpressionEvaluationWindow(team, ExpressionEvaluationWindow* self = new ExpressionEvaluationWindow(team,
language, listener, target); language, frame, thread, listener, target);
try { try {
self->_Init(); self->_Init();
@@ -216,7 +233,8 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message)
break; break;
fListener->ExpressionEvaluationRequested(fLanguage, fListener->ExpressionEvaluationRequested(fLanguage,
fExpressionInput->Text(), fCurrentEvaluationType); fExpressionInput->Text(), fCurrentEvaluationType, fStackFrame,
fThread);
break; break;
} }
@@ -16,7 +16,9 @@ class BButton;
class BStringView; class BStringView;
class BTextControl; class BTextControl;
class Team; class Team;
class Thread;
class SourceLanguage; class SourceLanguage;
class StackFrame;
class UserInterfaceListener; class UserInterfaceListener;
@@ -26,6 +28,8 @@ public:
ExpressionEvaluationWindow( ExpressionEvaluationWindow(
::Team* team, ::Team* team,
SourceLanguage* language, SourceLanguage* language,
StackFrame* frame,
::Thread* thread,
UserInterfaceListener* listener, UserInterfaceListener* listener,
BHandler* target); BHandler* target);
@@ -34,6 +38,8 @@ public:
static ExpressionEvaluationWindow* Create( static ExpressionEvaluationWindow* Create(
::Team* team, ::Team* team,
SourceLanguage* language, SourceLanguage* language,
StackFrame* frame,
::Thread* thread,
UserInterfaceListener* listener, UserInterfaceListener* listener,
BHandler* target); BHandler* target);
// throws // throws
@@ -60,6 +66,8 @@ private:
BStringView* fExpressionOutput; BStringView* fExpressionOutput;
BButton* fEvaluateButton; BButton* fEvaluateButton;
UserInterfaceListener* fListener; UserInterfaceListener* fListener;
StackFrame* fStackFrame;
::Thread* fThread;
BHandler* fCloseTarget; BHandler* fCloseTarget;
type_code fCurrentEvaluationType; type_code fCurrentEvaluationType;
}; };
@@ -356,7 +356,8 @@ TeamWindow::MessageReceived(BMessage* message)
BReference<SourceLanguage> languageReference(language, BReference<SourceLanguage> languageReference(language,
true); true);
fExpressionWindow = ExpressionEvaluationWindow::Create( fExpressionWindow = ExpressionEvaluationWindow::Create(
fTeam, language, fListener, this); fTeam, language, fActiveStackFrame, fActiveThread,
fListener, this);
if (fExpressionWindow != NULL) if (fExpressionWindow != NULL)
fExpressionWindow->Show(); fExpressionWindow->Show();
} catch (...) { } catch (...) {