Debugger: Rework expression parsing API.
ExpressionInfo: - No longer stores an explicit result type (this is inferred from evaluation of the expression itself now). - Introduce class ExpressionResult for returning the result of an expression computation. This can currently take the form of either a primitive value, or a value node object. - Adjust UserInterfaceListener and ExpressionInfo::Listener to take the above changes into account, and correspondingly adjust all callers/listeners. CLanguageExpressionEvaluator: - Introduce child class Operand. This subsumes the functionality that was previously in the separate Number class, and can represent a primitive value, a value node or a type. Also has functionality to implicity handle type promotion/inferring when performing calculations between operands. - Adjust expression parser to operate in terms of Operands rather than Numbers. This allows a number of improvements, most notably that an expression can now return a value node as a result rather than only a primitive number. This capability isn't yet fully used, but paves the way for future uses such as an expression that evaluates to a data member, a global variable, or an arbitrary pointer of a particular type. - Various cleanups/simplifications that were possible as a result of the above changes. ExpressionEvaluationWindow/ExpressionPromptWindow: - Remove type menu field, since the expression API no longer uses it. Adding/removing expressions in the VariablesView is temporarily disabled, pending some further rework there to properly handle the new result object.
This commit is contained in:
parent
8d48eb9311
commit
81c848a14a
@ -222,7 +222,6 @@ Application Debugger :
|
||||
|
||||
# types
|
||||
ArrayIndexPath.cpp
|
||||
Number.cpp
|
||||
TargetAddressRangeList.cpp
|
||||
ValueLocation.cpp
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "Team.h"
|
||||
#include "Tracing.h"
|
||||
#include "Value.h"
|
||||
#include "ValueLocation.h"
|
||||
#include "Worker.h"
|
||||
|
||||
|
||||
@ -63,7 +64,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void ExpressionEvaluated(ExpressionInfo* info, status_t result,
|
||||
Value* value)
|
||||
ExpressionResult* value)
|
||||
{
|
||||
fHandler->_HandleBreakpointConditionEvaluated(value);
|
||||
}
|
||||
@ -888,14 +889,8 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState)
|
||||
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);
|
||||
userBreakpoint->Condition());
|
||||
|
||||
if (expressionInfo == NULL)
|
||||
return false;
|
||||
@ -921,23 +916,13 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState)
|
||||
|
||||
teamLocker.Lock();
|
||||
|
||||
bool stop = false;
|
||||
if (fConditionResult == NULL)
|
||||
stop = true;
|
||||
else {
|
||||
BVariant value;
|
||||
if (!fConditionResult->ToVariant(value))
|
||||
stop = true;
|
||||
if (!value.TypeIsInteger(value.Type()))
|
||||
stop = true;
|
||||
stop = value.ToBool();
|
||||
fConditionResult->ReleaseReference();
|
||||
fConditionResult = NULL;
|
||||
}
|
||||
|
||||
if (stop)
|
||||
if (_CheckStopCondition()) {
|
||||
if (fConditionResult != NULL) {
|
||||
fConditionResult->ReleaseReference();
|
||||
fConditionResult = NULL;
|
||||
}
|
||||
return false;
|
||||
else {
|
||||
} else {
|
||||
_SetThreadState(THREAD_STATE_RUNNING, NULL,
|
||||
THREAD_STOPPED_UNKNOWN, BString());
|
||||
fDebuggerInterface->ContinueThread(fThread->ID());
|
||||
@ -951,7 +936,7 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState)
|
||||
|
||||
|
||||
void
|
||||
ThreadHandler::_HandleBreakpointConditionEvaluated(Value* value)
|
||||
ThreadHandler::_HandleBreakpointConditionEvaluated(ExpressionResult* value)
|
||||
{
|
||||
fConditionResult = value;
|
||||
if (fConditionResult != NULL)
|
||||
@ -960,6 +945,25 @@ ThreadHandler::_HandleBreakpointConditionEvaluated(Value* value)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ThreadHandler::_CheckStopCondition()
|
||||
{
|
||||
// if we we're unable to properly assess the expression result
|
||||
// in any way, fall back to behaving like an unconditional breakpoint.
|
||||
if (fConditionResult == NULL)
|
||||
return true;
|
||||
|
||||
if (fConditionResult->Kind() != EXPRESSION_RESULT_KIND_PRIMITIVE)
|
||||
return true;
|
||||
|
||||
BVariant value;
|
||||
if (!fConditionResult->PrimitiveValue()->ToVariant(value))
|
||||
return true;
|
||||
|
||||
return value.ToBool();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ThreadHandler::_HasExitedFrame(target_addr_t framePointer) const
|
||||
{
|
||||
|
@ -18,10 +18,10 @@
|
||||
|
||||
class BreakpointManager;
|
||||
class DebuggerInterface;
|
||||
class ExpressionResult;
|
||||
class ImageDebugInfoJobListener;
|
||||
class StackFrame;
|
||||
class Statement;
|
||||
class Value;
|
||||
class Worker;
|
||||
|
||||
|
||||
@ -102,7 +102,8 @@ private:
|
||||
bool _HandleBreakpointConditionIfNeeded(
|
||||
CpuState* cpuState);
|
||||
void _HandleBreakpointConditionEvaluated(
|
||||
Value* value);
|
||||
ExpressionResult* value);
|
||||
bool _CheckStopCondition();
|
||||
|
||||
bool _HandleBreakpointHitStep(CpuState* cpuState);
|
||||
bool _HandleSingleStepStep(CpuState* cpuState);
|
||||
@ -124,7 +125,7 @@ private:
|
||||
target_addr_t fPreviousFrameAddress;
|
||||
bool fSingleStepping;
|
||||
sem_id fConditionWaitSem;
|
||||
Value* fConditionResult;
|
||||
ExpressionResult* fConditionResult;
|
||||
|
||||
public:
|
||||
ThreadHandler* fNext;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "Value.h"
|
||||
#include "ValueNode.h"
|
||||
#include "ValueNodeManager.h"
|
||||
#include "Variable.h"
|
||||
|
||||
|
||||
ExpressionEvaluationJob::ExpressionEvaluationJob(Team* team,
|
||||
@ -89,10 +90,8 @@ ExpressionEvaluationJob::Do()
|
||||
}
|
||||
|
||||
ValueNode* neededNode = NULL;
|
||||
PrimitiveType* type = dynamic_cast<PrimitiveType*>(
|
||||
fExpressionInfo->ResultType());
|
||||
result = fLanguage->EvaluateExpression(fExpressionInfo->Expression(),
|
||||
type->TypeConstant(), fManager, fResultValue, neededNode);
|
||||
fManager, fResultValue, neededNode);
|
||||
if (neededNode != NULL) {
|
||||
result = ResolveNodeValue(neededNode);
|
||||
if (State() == JOB_STATE_WAITING)
|
||||
|
@ -19,6 +19,7 @@ class BVariant;
|
||||
class CpuState;
|
||||
class DebuggerInterface;
|
||||
class ExpressionInfo;
|
||||
class ExpressionResult;
|
||||
class Function;
|
||||
class FunctionInstance;
|
||||
class Image;
|
||||
@ -245,7 +246,7 @@ public:
|
||||
virtual const JobKey& Key() const;
|
||||
virtual status_t Do();
|
||||
|
||||
Value* GetResultValue() const { return fResultValue; }
|
||||
ExpressionResult* GetResult() const { return fResultValue; }
|
||||
|
||||
private:
|
||||
status_t ResolveNodeValue(ValueNode* node);
|
||||
@ -261,7 +262,7 @@ private:
|
||||
StackFrame* fFrame;
|
||||
Thread* fThread;
|
||||
ValueNodeManager* fManager;
|
||||
Value* fResultValue;
|
||||
ExpressionResult* fResultValue;
|
||||
};
|
||||
|
||||
|
||||
|
@ -6,70 +6,123 @@
|
||||
|
||||
#include "ExpressionInfo.h"
|
||||
|
||||
#include "Type.h"
|
||||
#include "Value.h"
|
||||
#include "ValueNode.h"
|
||||
|
||||
|
||||
// #pragma mark - ExpressionResult
|
||||
|
||||
|
||||
ExpressionResult::ExpressionResult()
|
||||
:
|
||||
fResultKind(EXPRESSION_RESULT_KIND_UNKNOWN),
|
||||
fPrimitiveValue(NULL),
|
||||
fValueNodeValue(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ExpressionResult::~ExpressionResult()
|
||||
{
|
||||
if (fPrimitiveValue != NULL)
|
||||
fPrimitiveValue->ReleaseReference();
|
||||
|
||||
if (fValueNodeValue != NULL)
|
||||
fValueNodeValue->ReleaseReference();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExpressionResult::SetToPrimitive(Value* value)
|
||||
{
|
||||
_Unset();
|
||||
|
||||
fPrimitiveValue = value;
|
||||
if (fPrimitiveValue != NULL) {
|
||||
fPrimitiveValue->AcquireReference();
|
||||
fResultKind = EXPRESSION_RESULT_KIND_PRIMITIVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExpressionResult::SetToValueNode(ValueNodeChild* child)
|
||||
{
|
||||
_Unset();
|
||||
|
||||
fValueNodeValue = child;
|
||||
if (fValueNodeValue != NULL) {
|
||||
fValueNodeValue->AcquireReference();
|
||||
fResultKind = EXPRESSION_RESULT_KIND_VALUE_NODE;
|
||||
}
|
||||
|
||||
// if the child has a node with a resolved value, store
|
||||
// it as a primitive, so the consumer of the expression
|
||||
// can use it as-is if desired.
|
||||
|
||||
ValueNode* node = child->Node();
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
fPrimitiveValue = node->GetValue();
|
||||
if (fPrimitiveValue != NULL)
|
||||
fPrimitiveValue->AcquireReference();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExpressionResult::_Unset()
|
||||
{
|
||||
if (fPrimitiveValue != NULL) {
|
||||
fPrimitiveValue->ReleaseReference();
|
||||
fPrimitiveValue = NULL;
|
||||
}
|
||||
|
||||
if (fValueNodeValue != NULL) {
|
||||
fValueNodeValue->ReleaseReference();
|
||||
fValueNodeValue = NULL;
|
||||
}
|
||||
|
||||
fResultKind = EXPRESSION_RESULT_KIND_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - ExpressionInfo
|
||||
|
||||
|
||||
ExpressionInfo::ExpressionInfo()
|
||||
:
|
||||
fExpression(),
|
||||
fResultType(NULL)
|
||||
fExpression()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ExpressionInfo::ExpressionInfo(const ExpressionInfo& other)
|
||||
:
|
||||
fExpression(other.fExpression),
|
||||
fResultType(other.fResultType)
|
||||
fExpression(other.fExpression)
|
||||
{
|
||||
if (fResultType != NULL)
|
||||
fResultType->AcquireReference();
|
||||
}
|
||||
|
||||
|
||||
ExpressionInfo::~ExpressionInfo()
|
||||
{
|
||||
SetResultType(NULL);
|
||||
}
|
||||
|
||||
|
||||
ExpressionInfo::ExpressionInfo(const BString& expression, Type* resultType)
|
||||
ExpressionInfo::ExpressionInfo(const BString& expression)
|
||||
:
|
||||
fExpression(expression),
|
||||
fResultType(resultType)
|
||||
fExpression(expression)
|
||||
{
|
||||
if (resultType != NULL)
|
||||
resultType->AcquireReference();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExpressionInfo::SetTo(const BString& expression, Type* resultType)
|
||||
{
|
||||
SetExpression(expression);
|
||||
SetResultType(resultType);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExpressionInfo::SetExpression(const BString& expression)
|
||||
ExpressionInfo::SetTo(const BString& expression)
|
||||
{
|
||||
fExpression = expression;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExpressionInfo::SetResultType(Type* resultType)
|
||||
{
|
||||
if (fResultType != NULL)
|
||||
fResultType->ReleaseReference();
|
||||
|
||||
fResultType = resultType;
|
||||
if (fResultType != NULL)
|
||||
fResultType->AcquireReference();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExpressionInfo::AddListener(Listener* listener)
|
||||
{
|
||||
@ -85,7 +138,8 @@ ExpressionInfo::RemoveListener(Listener* listener)
|
||||
|
||||
|
||||
void
|
||||
ExpressionInfo::NotifyExpressionEvaluated(status_t result, Value* value)
|
||||
ExpressionInfo::NotifyExpressionEvaluated(status_t result,
|
||||
ExpressionResult* value)
|
||||
{
|
||||
for (ListenerList::Iterator it = fListeners.GetIterator();
|
||||
Listener* listener = it.Next();) {
|
||||
|
@ -10,9 +10,44 @@
|
||||
|
||||
#include <Referenceable.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
#include <Variant.h>
|
||||
|
||||
|
||||
class Type;
|
||||
class Value;
|
||||
class ValueNodeChild;
|
||||
|
||||
|
||||
enum expression_result_kind {
|
||||
EXPRESSION_RESULT_KIND_UNKNOWN = 0,
|
||||
EXPRESSION_RESULT_KIND_PRIMITIVE,
|
||||
EXPRESSION_RESULT_KIND_VALUE_NODE
|
||||
};
|
||||
|
||||
|
||||
class ExpressionResult : public BReferenceable {
|
||||
public:
|
||||
ExpressionResult();
|
||||
virtual ~ExpressionResult();
|
||||
|
||||
|
||||
expression_result_kind Kind() const { return fResultKind; }
|
||||
|
||||
Value* PrimitiveValue() const
|
||||
{ return fPrimitiveValue; }
|
||||
ValueNodeChild* ValueNodeValue() const
|
||||
{ return fValueNodeValue; }
|
||||
|
||||
void SetToPrimitive(Value* value);
|
||||
void SetToValueNode(ValueNodeChild* child);
|
||||
|
||||
private:
|
||||
void _Unset();
|
||||
|
||||
private:
|
||||
expression_result_kind fResultKind;
|
||||
Value* fPrimitiveValue;
|
||||
ValueNodeChild* fValueNodeValue;
|
||||
};
|
||||
|
||||
|
||||
class ExpressionInfo : public BReferenceable {
|
||||
@ -22,31 +57,24 @@ public:
|
||||
public:
|
||||
ExpressionInfo();
|
||||
ExpressionInfo(const ExpressionInfo& other);
|
||||
ExpressionInfo(const BString& expression,
|
||||
Type* resultType);
|
||||
ExpressionInfo(const BString& expression);
|
||||
virtual ~ExpressionInfo();
|
||||
|
||||
void SetTo(const BString& expression,
|
||||
Type* resultType);
|
||||
void SetTo(const BString& expression);
|
||||
|
||||
const BString& Expression() const { return fExpression; }
|
||||
void SetExpression(const BString& expression);
|
||||
|
||||
Type* ResultType() const { return fResultType; }
|
||||
void SetResultType(Type* resultType);
|
||||
|
||||
void AddListener(Listener* listener);
|
||||
void RemoveListener(Listener* listener);
|
||||
|
||||
void NotifyExpressionEvaluated(status_t result,
|
||||
Value* value);
|
||||
ExpressionResult* value);
|
||||
|
||||
private:
|
||||
typedef DoublyLinkedList<Listener> ListenerList;
|
||||
|
||||
private:
|
||||
BString fExpression;
|
||||
Type* fResultType;
|
||||
ListenerList fListeners;
|
||||
};
|
||||
|
||||
@ -56,7 +84,8 @@ public:
|
||||
virtual ~Listener();
|
||||
|
||||
virtual void ExpressionEvaluated(ExpressionInfo* info,
|
||||
status_t result, Value* value) = 0;
|
||||
status_t result,
|
||||
ExpressionResult* value) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -11,11 +11,9 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "CLanguageExpressionEvaluator.h"
|
||||
#include "FloatValue.h"
|
||||
#include "IntegerValue.h"
|
||||
#include "Number.h"
|
||||
#include "StringValue.h"
|
||||
#include "ExpressionInfo.h"
|
||||
#include "TeamTypeInformation.h"
|
||||
#include "StringValue.h"
|
||||
#include "Type.h"
|
||||
#include "TypeLookupConstraints.h"
|
||||
|
||||
@ -167,46 +165,28 @@ CLanguageFamily::ParseTypeExpression(const BString& expression,
|
||||
|
||||
|
||||
status_t
|
||||
CLanguageFamily::EvaluateExpression(const BString& expression, type_code type,
|
||||
ValueNodeManager* manager, Value*& _output, ValueNode*& _neededNode)
|
||||
CLanguageFamily::EvaluateExpression(const BString& expression,
|
||||
ValueNodeManager* manager, ExpressionResult*& _output,
|
||||
ValueNode*& _neededNode)
|
||||
{
|
||||
_output = NULL;
|
||||
_neededNode = NULL;
|
||||
CLanguageExpressionEvaluator evaluator;
|
||||
Number result;
|
||||
try {
|
||||
result = evaluator.Evaluate(expression, type, manager);
|
||||
BVariant resultValue = result.GetValue();
|
||||
switch (type) {
|
||||
case B_INT8_TYPE:
|
||||
case B_UINT8_TYPE:
|
||||
case B_INT16_TYPE:
|
||||
case B_UINT16_TYPE:
|
||||
case B_INT32_TYPE:
|
||||
case B_UINT32_TYPE:
|
||||
case B_INT64_TYPE:
|
||||
case B_UINT64_TYPE:
|
||||
_output = new(std::nothrow) IntegerValue(resultValue);
|
||||
break;
|
||||
|
||||
case B_FLOAT_TYPE:
|
||||
_output = new(std::nothrow) FloatValue(resultValue.ToFloat());
|
||||
break;
|
||||
|
||||
case B_DOUBLE_TYPE:
|
||||
_output = new(std::nothrow) FloatValue(resultValue.ToDouble());
|
||||
break;
|
||||
}
|
||||
|
||||
if (_output == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
_output = evaluator.Evaluate(expression, manager);
|
||||
return B_OK;
|
||||
} catch (ParseException ex) {
|
||||
BString stringValue;
|
||||
stringValue.SetToFormat("Parse error at position %" B_PRId32 ": %s",
|
||||
BString error;
|
||||
error.SetToFormat("Parse error at position %" B_PRId32 ": %s",
|
||||
ex.position, ex.message.String());
|
||||
_output = new(std::nothrow) StringValue(stringValue);
|
||||
StringValue* value = new(std::nothrow) StringValue(error.String());
|
||||
if (value == NULL)
|
||||
return B_NO_MEMORY;
|
||||
BReference<Value> valueReference(value, true);
|
||||
_output = new(std::nothrow) ExpressionResult();
|
||||
if (_output == NULL)
|
||||
return B_NO_MEMORY;
|
||||
_output->SetToPrimitive(value);
|
||||
return B_BAD_DATA;
|
||||
} catch (ValueNeededException ex) {
|
||||
_neededNode = ex.value;
|
||||
|
@ -22,8 +22,9 @@ public:
|
||||
Type*& _resultType) const;
|
||||
|
||||
virtual status_t EvaluateExpression(const BString& expression,
|
||||
type_code type, ValueNodeManager* manager,
|
||||
Value*& _output, ValueNode*& _neededNode);
|
||||
ValueNodeManager* manager,
|
||||
ExpressionResult*& _output,
|
||||
ValueNode*& _neededNode);
|
||||
|
||||
protected:
|
||||
virtual bool IsModifierValid(char modifier) const = 0;
|
||||
|
@ -30,7 +30,7 @@ SourceLanguage::ParseTypeExpression(const BString& expression,
|
||||
|
||||
status_t
|
||||
SourceLanguage::EvaluateExpression(const BString& expression,
|
||||
type_code type, ValueNodeManager* manager, Value*& _resultValue,
|
||||
ValueNodeManager* manager, ExpressionResult*& _resultValue,
|
||||
ValueNode*& _neededNode)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
|
@ -11,10 +11,10 @@
|
||||
|
||||
|
||||
class BString;
|
||||
class ExpressionResult;
|
||||
class SyntaxHighlighter;
|
||||
class TeamTypeInformation;
|
||||
class Type;
|
||||
class Value;
|
||||
class ValueNode;
|
||||
class ValueNodeManager;
|
||||
|
||||
@ -34,8 +34,9 @@ public:
|
||||
Type*& _resultType) const;
|
||||
|
||||
virtual status_t EvaluateExpression(const BString& expression,
|
||||
type_code type, ValueNodeManager* manager,
|
||||
Value*& _output, ValueNode*& _neededNode);
|
||||
ValueNodeManager* manager,
|
||||
ExpressionResult*& _output,
|
||||
ValueNode*& _neededNode);
|
||||
};
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,7 @@
|
||||
class ValueNode;
|
||||
class ValueNodeChild;
|
||||
class ValueNodeManager;
|
||||
class Variable;
|
||||
|
||||
|
||||
class ParseException {
|
||||
@ -38,6 +39,7 @@ class ParseException {
|
||||
int32 position;
|
||||
};
|
||||
|
||||
|
||||
class ValueNeededException {
|
||||
public:
|
||||
ValueNeededException(ValueNode* node)
|
||||
@ -50,6 +52,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class ExpressionResult;
|
||||
class Number;
|
||||
|
||||
|
||||
@ -59,31 +62,28 @@ class CLanguageExpressionEvaluator {
|
||||
CLanguageExpressionEvaluator();
|
||||
~CLanguageExpressionEvaluator();
|
||||
|
||||
Number Evaluate(const char* expressionString,
|
||||
type_code type, ValueNodeManager* manager);
|
||||
ExpressionResult* Evaluate(const char* expressionString,
|
||||
ValueNodeManager* manager);
|
||||
|
||||
private:
|
||||
class Operand;
|
||||
struct Token;
|
||||
class Tokenizer;
|
||||
|
||||
private:
|
||||
Number _ParseSum();
|
||||
Number _ParseProduct();
|
||||
Number _ParsePower();
|
||||
Number _ParseUnary();
|
||||
Number _ParseIdentifier(ValueNode* parentNode = NULL);
|
||||
Number _ParseAtom();
|
||||
Operand _ParseSum();
|
||||
Operand _ParseProduct();
|
||||
Operand _ParsePower();
|
||||
Operand _ParseUnary();
|
||||
Operand _ParseIdentifier(ValueNode* parentNode = NULL);
|
||||
Operand _ParseAtom();
|
||||
|
||||
void _EatToken(int32 type);
|
||||
|
||||
void _RequestValueIfNeeded(const Token& token,
|
||||
ValueNodeChild* child);
|
||||
|
||||
void _CoerceTypeIfNeeded(const Token& token,
|
||||
Number& _number);
|
||||
|
||||
Tokenizer* fTokenizer;
|
||||
type_code fCurrentType;
|
||||
ValueNodeManager* fNodeManager;
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NUMBER_H
|
||||
#define NUMBER_H
|
||||
|
||||
#include <TypeConstants.h>
|
||||
|
||||
#include "Variant.h"
|
||||
|
||||
|
||||
class BString;
|
||||
|
||||
|
||||
class Number {
|
||||
public:
|
||||
Number();
|
||||
virtual ~Number();
|
||||
Number(type_code type, const BString& value);
|
||||
Number(const BVariant& value);
|
||||
Number(const Number& other);
|
||||
|
||||
void SetTo(type_code type, const BString& value,
|
||||
int32 base = 10);
|
||||
void SetTo(const BVariant& value);
|
||||
|
||||
type_code Type() const { return fValue.Type(); }
|
||||
|
||||
Number& operator=(const Number& rhs);
|
||||
Number& operator+=(const Number& rhs);
|
||||
Number& operator-=(const Number& rhs);
|
||||
Number& operator/=(const Number& rhs);
|
||||
Number& operator*=(const Number& rhs);
|
||||
Number& operator%=(const Number& rhs);
|
||||
|
||||
Number& operator&=(const Number& rhs);
|
||||
Number& operator|=(const Number& rhs);
|
||||
Number& operator^=(const Number& rhs);
|
||||
|
||||
Number operator-() const;
|
||||
Number operator~() const;
|
||||
|
||||
int operator<(const Number& rhs) const;
|
||||
int operator<=(const Number& rhs) const;
|
||||
int operator>(const Number& rhs) const;
|
||||
int operator>=(const Number& rhs) const;
|
||||
int operator==(const Number& rhs) const;
|
||||
int operator!=(const Number& rhs) const;
|
||||
|
||||
BVariant GetValue() const;
|
||||
|
||||
private:
|
||||
BVariant fValue;
|
||||
};
|
||||
|
||||
|
||||
#endif // NUMBER_H
|
@ -12,8 +12,9 @@
|
||||
|
||||
#include "StackTrace.h"
|
||||
#include "UserInterface.h"
|
||||
#include "Value.h"
|
||||
#include "ValueNodeManager.h"
|
||||
#include "Variable.h"
|
||||
|
||||
|
||||
// NOTE: This is a simple work-around for EditLine not having any kind of user
|
||||
// data field. Hence in _GetPrompt() we don't have access to the context object.
|
||||
@ -29,7 +30,7 @@ static CliContext* sCurrentContext;
|
||||
struct CliContext::Event : DoublyLinkedListLinkImpl<CliContext::Event> {
|
||||
Event(int type, Thread* thread = NULL, TeamMemoryBlock* block = NULL,
|
||||
ExpressionInfo* info = NULL, status_t expressionResult = B_OK,
|
||||
Value* expressionValue = NULL)
|
||||
ExpressionResult* expressionValue = NULL)
|
||||
:
|
||||
fType(type),
|
||||
fThreadReference(thread),
|
||||
@ -65,7 +66,7 @@ struct CliContext::Event : DoublyLinkedListLinkImpl<CliContext::Event> {
|
||||
return fExpressionResult;
|
||||
}
|
||||
|
||||
Value* GetExpressionValue() const
|
||||
ExpressionResult* GetExpressionValue() const
|
||||
{
|
||||
return fExpressionValue.Get();
|
||||
}
|
||||
@ -77,7 +78,7 @@ private:
|
||||
BReference<TeamMemoryBlock> fMemoryBlockReference;
|
||||
BReference<ExpressionInfo> fExpressionInfo;
|
||||
status_t fExpressionResult;
|
||||
BReference<Value> fExpressionValue;
|
||||
BReference<ExpressionResult> fExpressionValue;
|
||||
};
|
||||
|
||||
|
||||
@ -509,7 +510,7 @@ CliContext::ThreadStackTraceChanged(const Team::ThreadEvent& threadEvent)
|
||||
|
||||
void
|
||||
CliContext::ExpressionEvaluated(ExpressionInfo* info, status_t result,
|
||||
Value* value)
|
||||
ExpressionResult* value)
|
||||
{
|
||||
_QueueEvent(
|
||||
new(std::nothrow) Event(EVENT_EXPRESSION_EVALUATED,
|
||||
|
@ -85,7 +85,7 @@ public:
|
||||
{ return fExpressionInfo; }
|
||||
status_t GetExpressionResult() const
|
||||
{ return fExpressionResult; }
|
||||
Value* GetExpressionValue() const
|
||||
ExpressionResult* GetExpressionValue() const
|
||||
{ return fExpressionValue; }
|
||||
|
||||
const char* PromptUser(const char* prompt);
|
||||
@ -120,7 +120,7 @@ private:
|
||||
|
||||
// ExpressionInfo::Listener
|
||||
virtual void ExpressionEvaluated(ExpressionInfo* info,
|
||||
status_t result, Value* value);
|
||||
status_t result, ExpressionResult* value);
|
||||
|
||||
// ValueNodeContainer::Listener
|
||||
virtual void ValueNodeChanged(ValueNodeChild* nodeChild,
|
||||
@ -160,7 +160,7 @@ private:
|
||||
|
||||
ExpressionInfo* fExpressionInfo;
|
||||
status_t fExpressionResult;
|
||||
Value* fExpressionValue;
|
||||
ExpressionResult* fExpressionValue;
|
||||
|
||||
EventList fPendingEvents;
|
||||
};
|
||||
|
@ -18,12 +18,12 @@
|
||||
|
||||
#include "CliContext.h"
|
||||
#include "CppLanguage.h"
|
||||
#include "SyntheticPrimitiveType.h"
|
||||
#include "Team.h"
|
||||
#include "TeamMemoryBlock.h"
|
||||
#include "UiUtils.h"
|
||||
#include "UserInterface.h"
|
||||
#include "Value.h"
|
||||
#include "Variable.h"
|
||||
|
||||
|
||||
CliDumpMemoryCommand::CliDumpMemoryCommand()
|
||||
@ -60,22 +60,7 @@ CliDumpMemoryCommand::Execute(int argc, const char* const* argv,
|
||||
ExpressionInfo* info = context.GetExpressionInfo();
|
||||
|
||||
target_addr_t address = 0;
|
||||
|
||||
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]);
|
||||
info->SetTo(argv[1]);
|
||||
|
||||
context.GetUserInterfaceListener()->ExpressionEvaluationRequested(
|
||||
fLanguage, info);
|
||||
@ -84,14 +69,17 @@ CliDumpMemoryCommand::Execute(int argc, const char* const* argv,
|
||||
return;
|
||||
|
||||
BString errorMessage;
|
||||
Value* value = context.GetExpressionValue();
|
||||
if (value != NULL) {
|
||||
BVariant variantValue;
|
||||
value->ToVariant(variantValue);
|
||||
if (variantValue.Type() == B_UINT64_TYPE)
|
||||
address = variantValue.ToUInt64();
|
||||
else
|
||||
value->ToString(errorMessage);
|
||||
ExpressionResult* result = context.GetExpressionValue();
|
||||
if (result != NULL) {
|
||||
if (result->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) {
|
||||
Value* value = result->PrimitiveValue();
|
||||
BVariant variantValue;
|
||||
value->ToVariant(variantValue);
|
||||
if (variantValue.Type() == B_STRING_TYPE)
|
||||
errorMessage.SetTo(variantValue.ToString());
|
||||
else
|
||||
address = variantValue.ToUInt64();
|
||||
}
|
||||
} else
|
||||
errorMessage = strerror(context.GetExpressionResult());
|
||||
|
||||
|
@ -19,12 +19,11 @@
|
||||
#include "Architecture.h"
|
||||
#include "CppLanguage.h"
|
||||
#include "GuiTeamUiSettings.h"
|
||||
#include "IntegerValue.h"
|
||||
#include "MemoryView.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "SyntheticPrimitiveType.h"
|
||||
#include "Team.h"
|
||||
#include "UserInterface.h"
|
||||
#include "Value.h"
|
||||
|
||||
|
||||
enum {
|
||||
@ -94,9 +93,7 @@ void
|
||||
InspectorWindow::_Init()
|
||||
{
|
||||
fLanguage = new CppLanguage();
|
||||
::Type* type = new SyntheticPrimitiveType(B_UINT64_TYPE);
|
||||
BReference< ::Type> typeReference(type);
|
||||
fExpressionInfo = new ExpressionInfo(NULL, type);
|
||||
fExpressionInfo = new ExpressionInfo();
|
||||
fExpressionInfo->AddListener(this);
|
||||
|
||||
BScrollView* scrollView;
|
||||
@ -236,7 +233,7 @@ InspectorWindow::MessageReceived(BMessage* message)
|
||||
if (fAddressInput->TextView()->TextLength() == 0)
|
||||
break;
|
||||
|
||||
fExpressionInfo->SetExpression(fAddressInput->Text());
|
||||
fExpressionInfo->SetTo(fAddressInput->Text());
|
||||
|
||||
fListener->ExpressionEvaluationRequested(fLanguage,
|
||||
fExpressionInfo);
|
||||
@ -247,18 +244,22 @@ InspectorWindow::MessageReceived(BMessage* message)
|
||||
case MSG_EXPRESSION_EVALUATED:
|
||||
{
|
||||
BString errorMessage;
|
||||
BReference<Value> reference;
|
||||
Value* value = NULL;
|
||||
BReference<ExpressionResult> reference;
|
||||
ExpressionResult* value = NULL;
|
||||
if (message->FindPointer("value",
|
||||
reinterpret_cast<void**>(&value)) == B_OK) {
|
||||
reference.SetTo(value, true);
|
||||
BVariant variant;
|
||||
value->ToVariant(variant);
|
||||
if (variant.Type() == B_UINT64_TYPE) {
|
||||
_SetToAddress(variant.ToUInt64());
|
||||
break;
|
||||
} else
|
||||
value->ToString(errorMessage);
|
||||
if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) {
|
||||
Value* primitive = value->PrimitiveValue();
|
||||
BVariant variantValue;
|
||||
primitive->ToVariant(variantValue);
|
||||
if (variantValue.Type() == B_STRING_TYPE) {
|
||||
errorMessage.SetTo(variantValue.ToString());
|
||||
} else {
|
||||
_SetToAddress(variantValue.ToUInt64());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status_t result = message->FindInt32("result");
|
||||
errorMessage.SetToFormat("Failed to evaluate expression: %s",
|
||||
@ -385,11 +386,11 @@ InspectorWindow::TargetAddressChanged(target_addr_t address)
|
||||
|
||||
void
|
||||
InspectorWindow::ExpressionEvaluated(ExpressionInfo* info, status_t result,
|
||||
Value* value)
|
||||
ExpressionResult* value)
|
||||
{
|
||||
BMessage message(MSG_EXPRESSION_EVALUATED);
|
||||
message.AddInt32("result", result);
|
||||
BReference<Value> reference;
|
||||
BReference<ExpressionResult> reference;
|
||||
if (value != NULL) {
|
||||
reference.SetTo(value);
|
||||
message.AddPointer("value", value);
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
|
||||
// ExpressionInfo::Listener
|
||||
virtual void ExpressionEvaluated(ExpressionInfo* info,
|
||||
status_t result, Value* value);
|
||||
status_t result, ExpressionResult* value);
|
||||
|
||||
status_t LoadSettings(
|
||||
const GuiTeamUiSettings& settings);
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "AutoLocker.h"
|
||||
|
||||
#include "IntegerValue.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "SourceLanguage.h"
|
||||
#include "StackFrame.h"
|
||||
@ -21,12 +22,6 @@
|
||||
#include "Thread.h"
|
||||
#include "UiUtils.h"
|
||||
#include "UserInterface.h"
|
||||
#include "Value.h"
|
||||
|
||||
|
||||
enum {
|
||||
MSG_CHANGE_EVALUATION_TYPE = 'chet'
|
||||
};
|
||||
|
||||
|
||||
ExpressionEvaluationWindow::ExpressionEvaluationWindow(
|
||||
@ -91,9 +86,8 @@ ExpressionEvaluationWindow::Create(SourceLanguage* language, StackFrame* frame,
|
||||
void
|
||||
ExpressionEvaluationWindow::_Init()
|
||||
{
|
||||
::Type* type = new SyntheticPrimitiveType(B_INT64_TYPE);
|
||||
BReference< ::Type> typeReference(type, true);
|
||||
fExpressionInfo = new ExpressionInfo(NULL, type);
|
||||
fExpressionInfo = new ExpressionInfo;
|
||||
fExpressionInfo->AddListener(this);
|
||||
|
||||
fExpressionInput = new BTextControl("Expression:", NULL,
|
||||
new BMessage(MSG_EVALUATE_EXPRESSION));
|
||||
@ -107,16 +101,11 @@ ExpressionEvaluationWindow::_Init()
|
||||
fExpressionOutput->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,
|
||||
B_SIZE_UNSET));
|
||||
|
||||
BMenuField* typeField = new BMenuField("Type:", _BuildTypesMenu());
|
||||
typeField->Menu()->SetTargetForItems(this);
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL)
|
||||
.SetInsets(B_USE_DEFAULT_SPACING)
|
||||
.AddGroup(B_HORIZONTAL, 4.0f)
|
||||
.Add(labelItem)
|
||||
.Add(inputItem)
|
||||
.Add(typeField->CreateLabelLayoutItem())
|
||||
.Add(typeField->CreateMenuBarLayoutItem())
|
||||
.End()
|
||||
.AddGroup(B_HORIZONTAL, 4.0f)
|
||||
.Add(new BStringView("OutputLabelView", "Result:"))
|
||||
@ -130,54 +119,18 @@ ExpressionEvaluationWindow::_Init()
|
||||
|
||||
fExpressionInput->SetTarget(this);
|
||||
fEvaluateButton->SetTarget(this);
|
||||
fEvaluateButton->MakeDefault(true);
|
||||
fExpressionInput->TextView()->MakeFocus(true);
|
||||
}
|
||||
|
||||
|
||||
BMenu*
|
||||
ExpressionEvaluationWindow::_BuildTypesMenu()
|
||||
{
|
||||
BMenu* menu = new BMenu("Types");
|
||||
menu->SetLabelFromMarked(true);
|
||||
|
||||
_AddMenuItemForType(menu, B_INT8_TYPE);
|
||||
_AddMenuItemForType(menu, B_UINT8_TYPE);
|
||||
_AddMenuItemForType(menu, B_INT16_TYPE);
|
||||
_AddMenuItemForType(menu, B_UINT16_TYPE);
|
||||
_AddMenuItemForType(menu, B_INT32_TYPE);
|
||||
_AddMenuItemForType(menu, B_UINT32_TYPE);
|
||||
BMenuItem* item = _AddMenuItemForType(menu, B_INT64_TYPE);
|
||||
if (item != NULL)
|
||||
item->SetMarked(true);
|
||||
|
||||
_AddMenuItemForType(menu, B_UINT64_TYPE);
|
||||
_AddMenuItemForType(menu, B_FLOAT_TYPE);
|
||||
_AddMenuItemForType(menu, B_DOUBLE_TYPE);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
BMenuItem*
|
||||
ExpressionEvaluationWindow::_AddMenuItemForType(BMenu* menu, type_code type)
|
||||
{
|
||||
BMessage *message = new BMessage(MSG_CHANGE_EVALUATION_TYPE);
|
||||
message->AddInt32("type", type);
|
||||
|
||||
BMenuItem* item = new BMenuItem(UiUtils::TypeCodeToString(type), message);
|
||||
menu->AddItem(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExpressionEvaluationWindow::ExpressionEvaluated(ExpressionInfo* info,
|
||||
status_t result, Value* value)
|
||||
status_t result, ExpressionResult* value)
|
||||
{
|
||||
BMessage message(MSG_EXPRESSION_EVALUATED);
|
||||
message.AddInt32("result", result);
|
||||
BReference<Value> reference;
|
||||
BReference<ExpressionResult> reference;
|
||||
if (value != NULL) {
|
||||
message.AddPointer("value", value);
|
||||
reference.SetTo(value);
|
||||
@ -215,35 +168,16 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message)
|
||||
if (fExpressionInput->TextView()->TextLength() == 0)
|
||||
break;
|
||||
|
||||
fExpressionInfo->SetExpression(fExpressionInput->Text());
|
||||
fExpressionInfo->SetTo(fExpressionInput->Text());
|
||||
|
||||
fListener->ExpressionEvaluationRequested(fLanguage,
|
||||
fExpressionInfo, fStackFrame, fThread);
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_CHANGE_EVALUATION_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;
|
||||
}
|
||||
|
||||
case MSG_EXPRESSION_EVALUATED:
|
||||
{
|
||||
Value* value = NULL;
|
||||
BReference<Value> reference;
|
||||
ExpressionResult* value = NULL;
|
||||
BReference<ExpressionResult> reference;
|
||||
if (message->FindPointer("value",
|
||||
reinterpret_cast<void**>(&value)) == B_OK) {
|
||||
reference.SetTo(value, true);
|
||||
@ -251,14 +185,20 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message)
|
||||
|
||||
BString outputText;
|
||||
if (value != NULL) {
|
||||
BVariant variantValue;
|
||||
value->ToVariant(variantValue);
|
||||
if (variantValue.TypeIsInteger(variantValue.Type())) {
|
||||
value->ToString(outputText);
|
||||
outputText.SetToFormat("%#" B_PRIx64 " (%s)",
|
||||
variantValue.ToUInt64(), outputText.String());
|
||||
} else
|
||||
value->ToString(outputText);
|
||||
if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) {
|
||||
Value* primitive = value->PrimitiveValue();
|
||||
if (dynamic_cast<IntegerValue*>(primitive) != NULL) {
|
||||
BVariant variantValue;
|
||||
primitive->ToVariant(variantValue);
|
||||
primitive->ToString(outputText);
|
||||
outputText.SetToFormat("%#" B_PRIx64 " (%s)",
|
||||
variantValue.ToUInt64(), outputText.String());
|
||||
} else
|
||||
primitive->ToString(outputText);
|
||||
} else {
|
||||
outputText.SetToFormat("Unsupported result type: %d",
|
||||
value->Kind());
|
||||
}
|
||||
} else {
|
||||
status_t result;
|
||||
if (message->FindInt32("result", &result) != B_OK)
|
||||
@ -271,8 +211,6 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message)
|
||||
fExpressionOutput->SetText(outputText);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
|
@ -9,16 +9,12 @@
|
||||
#include <Window.h>
|
||||
|
||||
#include "ExpressionInfo.h"
|
||||
#include "types/Types.h"
|
||||
|
||||
|
||||
class BMenu;
|
||||
class BMenuItem;
|
||||
class BButton;
|
||||
class BStringView;
|
||||
class BTextControl;
|
||||
class Thread;
|
||||
class PrimitiveType;
|
||||
class SourceLanguage;
|
||||
class StackFrame;
|
||||
class UserInterfaceListener;
|
||||
@ -53,13 +49,10 @@ public:
|
||||
|
||||
private:
|
||||
void _Init();
|
||||
BMenu* _BuildTypesMenu();
|
||||
BMenuItem* _AddMenuItemForType(BMenu* menu,
|
||||
type_code type);
|
||||
|
||||
// ExpressionInfo::Listener
|
||||
virtual void ExpressionEvaluated(ExpressionInfo* info,
|
||||
status_t result, Value* value);
|
||||
status_t result, ExpressionResult* value);
|
||||
|
||||
private:
|
||||
SourceLanguage* fLanguage;
|
||||
|
@ -6,17 +6,10 @@
|
||||
|
||||
#include <Button.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <MenuField.h>
|
||||
#include <String.h>
|
||||
#include <TextControl.h>
|
||||
|
||||
#include "MessageCodes.h"
|
||||
#include "UiUtils.h"
|
||||
|
||||
|
||||
enum {
|
||||
MSG_CHANGE_EVALUATION_TYPE = 'chet',
|
||||
};
|
||||
|
||||
|
||||
ExpressionPromptWindow::ExpressionPromptWindow(BHandler* addTarget,
|
||||
@ -28,8 +21,7 @@ ExpressionPromptWindow::ExpressionPromptWindow(BHandler* addTarget,
|
||||
fCancelButton(NULL),
|
||||
fAddButton(NULL),
|
||||
fAddTarget(addTarget),
|
||||
fCloseTarget(closeTarget),
|
||||
fCurrentType(B_INT64_TYPE)
|
||||
fCloseTarget(closeTarget)
|
||||
{
|
||||
}
|
||||
|
||||
@ -68,16 +60,11 @@ ExpressionPromptWindow::_Init()
|
||||
inputItem->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
|
||||
labelItem->View()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
BMenuField* typeField = new BMenuField("Type:", _BuildTypesMenu());
|
||||
typeField->Menu()->SetTargetForItems(this);
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL)
|
||||
.SetInsets(B_USE_DEFAULT_SPACING)
|
||||
.AddGroup(B_HORIZONTAL, 4.0f)
|
||||
.Add(labelItem)
|
||||
.Add(inputItem)
|
||||
.Add(typeField->CreateLabelLayoutItem())
|
||||
.Add(typeField->CreateMenuBarLayoutItem())
|
||||
.End()
|
||||
.AddGroup(B_HORIZONTAL, 4.0f)
|
||||
.AddGlue()
|
||||
@ -95,43 +82,6 @@ ExpressionPromptWindow::_Init()
|
||||
}
|
||||
|
||||
|
||||
BMenu*
|
||||
ExpressionPromptWindow::_BuildTypesMenu()
|
||||
{
|
||||
BMenu* menu = new BMenu("Types");
|
||||
menu->SetLabelFromMarked(true);
|
||||
|
||||
_AddMenuItemForType(menu, B_INT8_TYPE);
|
||||
_AddMenuItemForType(menu, B_UINT8_TYPE);
|
||||
_AddMenuItemForType(menu, B_INT16_TYPE);
|
||||
_AddMenuItemForType(menu, B_UINT16_TYPE);
|
||||
_AddMenuItemForType(menu, B_INT32_TYPE);
|
||||
_AddMenuItemForType(menu, B_UINT32_TYPE);
|
||||
BMenuItem* item = _AddMenuItemForType(menu, B_INT64_TYPE);
|
||||
if (item != NULL)
|
||||
item->SetMarked(true);
|
||||
|
||||
_AddMenuItemForType(menu, B_UINT64_TYPE);
|
||||
_AddMenuItemForType(menu, B_FLOAT_TYPE);
|
||||
_AddMenuItemForType(menu, B_DOUBLE_TYPE);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
BMenuItem*
|
||||
ExpressionPromptWindow::_AddMenuItemForType(BMenu* menu, type_code type)
|
||||
{
|
||||
BMessage *message = new BMessage(MSG_CHANGE_EVALUATION_TYPE);
|
||||
message->AddInt32("type", type);
|
||||
|
||||
BMenuItem* item = new BMenuItem(UiUtils::TypeCodeToString(type), message);
|
||||
menu->AddItem(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExpressionPromptWindow::Show()
|
||||
{
|
||||
@ -154,17 +104,10 @@ void
|
||||
ExpressionPromptWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case MSG_CHANGE_EVALUATION_TYPE:
|
||||
{
|
||||
fCurrentType = message->FindInt32("type");
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_ADD_NEW_EXPRESSION:
|
||||
{
|
||||
BMessage addMessage(MSG_EXPRESSION_PROMPT_WINDOW_CLOSED);
|
||||
addMessage.AddString("expression", fExpressionInput->Text());
|
||||
addMessage.AddInt32("type", fCurrentType);
|
||||
addMessage.AddMessenger("target", BMessenger(fAddTarget));
|
||||
|
||||
BMessenger(fCloseTarget).SendMessage(&addMessage);
|
||||
|
@ -10,8 +10,6 @@
|
||||
|
||||
|
||||
class BButton;
|
||||
class BMenu;
|
||||
class BMenuItem;
|
||||
class BTextControl;
|
||||
|
||||
|
||||
@ -35,9 +33,6 @@ public:
|
||||
|
||||
private:
|
||||
void _Init();
|
||||
BMenu* _BuildTypesMenu();
|
||||
BMenuItem* _AddMenuItemForType(BMenu* menu,
|
||||
type_code type);
|
||||
|
||||
private:
|
||||
BTextControl* fExpressionInput;
|
||||
@ -45,7 +40,6 @@ private:
|
||||
BButton* fAddButton;
|
||||
BHandler* fAddTarget;
|
||||
BHandler* fCloseTarget;
|
||||
type_code fCurrentType;
|
||||
};
|
||||
|
||||
#endif // EXPRESSION_PROMPT_WINDOW_H
|
||||
|
@ -406,15 +406,12 @@ TeamWindow::MessageReceived(BMessage* message)
|
||||
fExpressionPromptWindow = NULL;
|
||||
|
||||
const char* expression;
|
||||
int32 type;
|
||||
BMessenger targetMessenger;
|
||||
if (message->FindString("expression", &expression) == B_OK
|
||||
&& message->FindInt32("type", &type) == B_OK
|
||||
&& message->FindMessenger("target", &targetMessenger)
|
||||
== B_OK) {
|
||||
BMessage addMessage(MSG_ADD_NEW_EXPRESSION);
|
||||
addMessage.AddString("expression", expression);
|
||||
addMessage.AddInt32("type", type);
|
||||
|
||||
targetMessenger.SendMessage(&addMessage);
|
||||
}
|
||||
|
@ -1944,18 +1944,11 @@ VariablesView::MessageReceived(BMessage* message)
|
||||
case MSG_ADD_NEW_EXPRESSION:
|
||||
{
|
||||
const char* expression;
|
||||
int32 type;
|
||||
Type* resultType;
|
||||
if (message->FindString("expression", &expression) != B_OK
|
||||
|| message->FindInt32("type", &type) != B_OK
|
||||
|| _GetTypeForTypeCode(type, resultType) != B_OK) {
|
||||
if (message->FindString("expression", &expression) != B_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
BReference<Type> typeReference(resultType, true);
|
||||
|
||||
ExpressionInfo* info;
|
||||
status_t error = _AddExpression(expression, resultType, info);
|
||||
status_t error = _AddExpression(expression, info);
|
||||
if (error != B_OK) {
|
||||
// TODO: notify user of failure
|
||||
break;
|
||||
@ -1969,14 +1962,14 @@ VariablesView::MessageReceived(BMessage* message)
|
||||
{
|
||||
ExpressionInfo* info;
|
||||
status_t result;
|
||||
Value* value = NULL;
|
||||
ExpressionResult* value = NULL;
|
||||
if (message->FindPointer("info",
|
||||
reinterpret_cast<void**>(&info)) != B_OK
|
||||
|| message->FindInt32("result", &result) != B_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
BReference<Value> valueReference;
|
||||
BReference<ExpressionResult> valueReference;
|
||||
if (message->FindPointer("value", reinterpret_cast<void**>(&value))
|
||||
== B_OK) {
|
||||
valueReference.SetTo(value, true);
|
||||
@ -2231,12 +2224,12 @@ VariablesView::TreeTableCellMouseDown(TreeTable* table,
|
||||
|
||||
void
|
||||
VariablesView::ExpressionEvaluated(ExpressionInfo* info, status_t result,
|
||||
Value* value)
|
||||
ExpressionResult* value)
|
||||
{
|
||||
BMessage message(MSG_EXPRESSION_EVALUATED);
|
||||
message.AddPointer("info", info);
|
||||
message.AddInt32("result", result);
|
||||
BReference<Value> valueReference;
|
||||
BReference<ExpressionResult> valueReference;
|
||||
|
||||
if (value != NULL) {
|
||||
valueReference.SetTo(value);
|
||||
@ -2417,6 +2410,7 @@ VariablesView::_GetContextActionsForNode(ModelNode* node,
|
||||
BPrivate::ObjectDeleter<ContextActionList> postActionListDeleter(
|
||||
_postActions);
|
||||
|
||||
#if 0
|
||||
result = _AddContextAction("Add watch expression" B_UTF8_ELLIPSIS,
|
||||
MSG_ADD_WATCH_EXPRESSION, _postActions, message);
|
||||
if (result != B_OK)
|
||||
@ -2429,6 +2423,7 @@ VariablesView::_GetContextActionsForNode(ModelNode* node,
|
||||
return result;
|
||||
message->AddPointer("node", node);
|
||||
}
|
||||
#endif
|
||||
|
||||
preActionListDeleter.Detach();
|
||||
postActionListDeleter.Detach();
|
||||
@ -2748,8 +2743,7 @@ VariablesView::_CopyVariableValueToClipboard()
|
||||
|
||||
|
||||
status_t
|
||||
VariablesView::_AddExpression(const char* expression, Type* resultType,
|
||||
ExpressionInfo*& _info)
|
||||
VariablesView::_AddExpression(const char* expression, ExpressionInfo*& _info)
|
||||
{
|
||||
// if our stack frame doesn't have an associated function,
|
||||
// we can't add an expression
|
||||
@ -2775,8 +2769,7 @@ VariablesView::_AddExpression(const char* expression, Type* resultType,
|
||||
}
|
||||
}
|
||||
|
||||
ExpressionInfo* info = new(std::nothrow) ExpressionInfo(expression,
|
||||
resultType);
|
||||
ExpressionInfo* info = new(std::nothrow) ExpressionInfo(expression);
|
||||
|
||||
if (info == NULL)
|
||||
return B_NO_MEMORY;
|
||||
@ -2829,7 +2822,7 @@ VariablesView::_RemoveExpression(ModelNode* node)
|
||||
status_t
|
||||
VariablesView::_AddExpressionNode(ExpressionInfo* info)
|
||||
{
|
||||
Type* type = info->ResultType();
|
||||
#if 0
|
||||
ExpressionValueNodeChild* child
|
||||
= new(std::nothrow) ExpressionValueNodeChild(info->Expression(), type);
|
||||
if (child == NULL)
|
||||
@ -2859,7 +2852,10 @@ VariablesView::_AddExpressionNode(ExpressionInfo* info)
|
||||
|
||||
expressionNodeReference.Detach();
|
||||
modelNodeReference.Detach();
|
||||
|
||||
return B_OK;
|
||||
#endif
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
@ -2890,7 +2886,7 @@ VariablesView::_RestoreExpressionNodes()
|
||||
|
||||
void
|
||||
VariablesView::_SetExpressionNodeValue(ExpressionInfo* info, status_t result,
|
||||
Value* value)
|
||||
ExpressionResult* value)
|
||||
{
|
||||
FunctionInstance* instance = fStackFrame->Function();
|
||||
if (instance == NULL)
|
||||
@ -2918,7 +2914,8 @@ VariablesView::_SetExpressionNodeValue(ExpressionInfo* info, status_t result,
|
||||
if (child->GetExpression() != info->Expression())
|
||||
continue;
|
||||
|
||||
child->Node()->SetLocationAndValue(NULL, value, result);
|
||||
child->Node()->SetLocationAndValue(NULL, value->PrimitiveValue(),
|
||||
result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ private:
|
||||
|
||||
// ExpressionInfo::Listener
|
||||
virtual void ExpressionEvaluated(ExpressionInfo* info,
|
||||
status_t result, Value* value);
|
||||
status_t result, ExpressionResult* value);
|
||||
|
||||
private:
|
||||
class ContainerListener;
|
||||
@ -110,7 +110,6 @@ private:
|
||||
void _CopyVariableValueToClipboard();
|
||||
|
||||
status_t _AddExpression(const char* expression,
|
||||
Type* resultType,
|
||||
ExpressionInfo*& _info);
|
||||
void _RemoveExpression(ModelNode* node);
|
||||
|
||||
@ -118,7 +117,7 @@ private:
|
||||
void _RestoreExpressionNodes();
|
||||
|
||||
void _SetExpressionNodeValue(ExpressionInfo* info,
|
||||
status_t result, Value* value);
|
||||
status_t result, ExpressionResult* value);
|
||||
|
||||
status_t _GetTypeForTypeCode(int32 typeCode,
|
||||
Type*& _resultType) const;
|
||||
|
@ -17,10 +17,10 @@
|
||||
|
||||
#include "Architecture.h"
|
||||
#include "CppLanguage.h"
|
||||
#include "IntegerValue.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "SyntheticPrimitiveType.h"
|
||||
#include "UserInterface.h"
|
||||
#include "Value.h"
|
||||
#include "Watchpoint.h"
|
||||
|
||||
|
||||
@ -91,21 +91,15 @@ 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 = new ExpressionInfo(text);
|
||||
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 = new ExpressionInfo(text);
|
||||
fLengthExpressionInfo->AddListener(this);
|
||||
|
||||
int32 maxDebugRegisters = 0;
|
||||
@ -170,11 +164,12 @@ WatchPromptWindow::Show()
|
||||
|
||||
void
|
||||
WatchPromptWindow::ExpressionEvaluated(ExpressionInfo* info, status_t result,
|
||||
Value* value)
|
||||
ExpressionResult* value)
|
||||
{
|
||||
BMessage message(MSG_EXPRESSION_EVALUATED);
|
||||
message.AddInt32("result", result);
|
||||
BReference<Value> reference;
|
||||
message.AddPointer("info", info);
|
||||
BReference<ExpressionResult> reference;
|
||||
if (value != NULL) {
|
||||
reference.SetTo(value);
|
||||
message.AddPointer("value", value);
|
||||
@ -192,20 +187,32 @@ WatchPromptWindow::MessageReceived(BMessage* message)
|
||||
case MSG_EXPRESSION_EVALUATED:
|
||||
{
|
||||
BString errorMessage;
|
||||
BReference<Value> reference;
|
||||
Value* value = NULL;
|
||||
BReference<ExpressionResult> reference;
|
||||
ExpressionResult* value = NULL;
|
||||
ExpressionInfo* info = NULL;
|
||||
if (message->FindPointer("info",
|
||||
reinterpret_cast<void**>(&info)) != B_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (message->FindPointer("value",
|
||||
reinterpret_cast<void**>(&value)) == B_OK) {
|
||||
reference.SetTo(value, true);
|
||||
BVariant variant;
|
||||
value->ToVariant(variant);
|
||||
if (variant.Type() == B_UINT64_TYPE) {
|
||||
fRequestedAddress = variant.ToUInt64();
|
||||
break;
|
||||
} else if (variant.Type() == B_INT32_TYPE)
|
||||
fRequestedLength = variant.ToInt32();
|
||||
else
|
||||
value->ToString(errorMessage);
|
||||
if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) {
|
||||
Value* primitive = value->PrimitiveValue();
|
||||
if (dynamic_cast<IntegerValue*>(primitive) != NULL) {
|
||||
BVariant resultVariant;
|
||||
primitive->ToVariant(resultVariant);
|
||||
if (info == fAddressExpressionInfo) {
|
||||
fRequestedAddress = resultVariant.ToUInt64();
|
||||
break;
|
||||
} else
|
||||
fRequestedLength = resultVariant.ToInt32();
|
||||
}
|
||||
else
|
||||
primitive->ToString(errorMessage);
|
||||
} else
|
||||
errorMessage.SetTo("Unsupported expression result.");
|
||||
} else {
|
||||
status_t result = message->FindInt32("result");
|
||||
errorMessage.SetToFormat("Failed to evaluate expression: %s",
|
||||
@ -237,11 +244,11 @@ WatchPromptWindow::MessageReceived(BMessage* message)
|
||||
fRequestedAddress = 0;
|
||||
fRequestedLength = 0;
|
||||
|
||||
fAddressExpressionInfo->SetExpression(fAddressInput->Text());
|
||||
fAddressExpressionInfo->SetTo(fAddressInput->Text());
|
||||
fListener->ExpressionEvaluationRequested(fLanguage,
|
||||
fAddressExpressionInfo);
|
||||
|
||||
fLengthExpressionInfo->SetExpression(fLengthInput->Text());
|
||||
fLengthExpressionInfo->SetTo(fLengthInput->Text());
|
||||
fListener->ExpressionEvaluationRequested(fLanguage,
|
||||
fLengthExpressionInfo);
|
||||
break;
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
|
||||
// ExpressionInfo::Listener
|
||||
virtual void ExpressionEvaluated(ExpressionInfo* info,
|
||||
status_t result, Value* value);
|
||||
status_t result, ExpressionResult* value);
|
||||
|
||||
private:
|
||||
void _Init();
|
||||
|
Loading…
Reference in New Issue
Block a user