mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 15:19:19 +02:00
FpDebug: implement 80 bit extended float (soft fpu) for cross debugging a win-32bit target from a 64bit IDE
This commit is contained in:
parent
7d011b8465
commit
d0a3a004df
@ -50,9 +50,9 @@ unit FpDbgDwarf;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, types, math, FpDbgInfo, FpDbgDwarfDataClasses,
|
Classes, SysUtils, types, math, FpDbgInfo, FpDbgDwarfDataClasses, FpdMemoryTools,
|
||||||
FpdMemoryTools, FpErrorMessages, FpDbgUtil, FpDbgDwarfConst, FpDbgCommon,
|
FpErrorMessages, FpDbgUtil, FpDbgDwarfConst, FpDbgCommon, DbgIntfBaseTypes, LazUTF8,
|
||||||
DbgIntfBaseTypes, LazUTF8, {$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif}, LazClasses;
|
LazLoggerBase, LazClasses, LazDebuggerIntfFloatTypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
TFpDwarfInfo = FpDbgDwarfDataClasses.TFpDwarfInfo;
|
TFpDwarfInfo = FpDbgDwarfDataClasses.TFpDwarfInfo;
|
||||||
@ -270,7 +270,7 @@ type
|
|||||||
function GetFieldFlags: TFpValueFieldFlags; override;
|
function GetFieldFlags: TFpValueFieldFlags; override;
|
||||||
function GetAsCardinal: QWord; override;
|
function GetAsCardinal: QWord; override;
|
||||||
function GetAsInteger: Int64; override;
|
function GetAsInteger: Int64; override;
|
||||||
function GetAsFloat: Extended; override;
|
function GetAsExtended: TDbgExtended; override;
|
||||||
procedure SetAsInteger(AValue: Int64); override;
|
procedure SetAsInteger(AValue: Int64); override;
|
||||||
procedure SetAsCardinal(AValue: QWord); override;
|
procedure SetAsCardinal(AValue: QWord); override;
|
||||||
end;
|
end;
|
||||||
@ -283,7 +283,7 @@ type
|
|||||||
protected
|
protected
|
||||||
function GetAsCardinal: QWord; override;
|
function GetAsCardinal: QWord; override;
|
||||||
function GetAsInteger: Int64; override;
|
function GetAsInteger: Int64; override;
|
||||||
function GetAsFloat: Extended; override;
|
function GetAsExtended: TDbgExtended; override;
|
||||||
procedure SetAsCardinal(AValue: QWord); override;
|
procedure SetAsCardinal(AValue: QWord); override;
|
||||||
function GetFieldFlags: TFpValueFieldFlags; override;
|
function GetFieldFlags: TFpValueFieldFlags; override;
|
||||||
end;
|
end;
|
||||||
@ -293,10 +293,21 @@ type
|
|||||||
TFpValueDwarfFloat = class(TFpValueDwarfNumeric) // TDbgDwarfSymbolValue
|
TFpValueDwarfFloat = class(TFpValueDwarfNumeric) // TDbgDwarfSymbolValue
|
||||||
// TODO: typecasts to int should convert
|
// TODO: typecasts to int should convert
|
||||||
private
|
private
|
||||||
FValue: Extended;
|
FFloatPrecission: TFpFloatPrecission;
|
||||||
|
FValue: record
|
||||||
|
case TFpFloatPrecission of
|
||||||
|
fpSingle: ( FValueExt: TDbgExtended; );
|
||||||
|
fpDouble: ( FValueDouble: Double; );
|
||||||
|
fpExtended: ( FValueSingle: Single; );
|
||||||
|
end;
|
||||||
protected
|
protected
|
||||||
|
procedure ReadFloatValue;
|
||||||
function GetFieldFlags: TFpValueFieldFlags; override;
|
function GetFieldFlags: TFpValueFieldFlags; override;
|
||||||
function GetAsFloat: Extended; override;
|
function GetAsSingle: Single; override;
|
||||||
|
function GetAsDouble: Double; override;
|
||||||
|
function GetAsExtended: TDbgExtended; override;
|
||||||
|
function GetFloatPrecission: TFpFloatPrecission; override;
|
||||||
|
function GetAsFloat: Extended; override; deprecated;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFpValueDwarfBoolean }
|
{ TFpValueDwarfBoolean }
|
||||||
@ -2349,7 +2360,7 @@ begin
|
|||||||
FIntValue := Result;
|
FIntValue := Result;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpValueDwarfInteger.GetAsFloat: Extended;
|
function TFpValueDwarfInteger.GetAsExtended: TDbgExtended;
|
||||||
begin
|
begin
|
||||||
Result := GetAsInteger;
|
Result := GetAsInteger;
|
||||||
end;
|
end;
|
||||||
@ -2405,7 +2416,7 @@ begin
|
|||||||
Result := Int64(GetAsCardinal);
|
Result := Int64(GetAsCardinal);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpValueDwarfCardinal.GetAsFloat: Extended;
|
function TFpValueDwarfCardinal.GetAsExtended: TDbgExtended;
|
||||||
begin
|
begin
|
||||||
Result := GetAsInteger;
|
Result := GetAsInteger;
|
||||||
end;
|
end;
|
||||||
@ -2436,36 +2447,128 @@ end;
|
|||||||
|
|
||||||
{ TFpValueDwarfFloat }
|
{ TFpValueDwarfFloat }
|
||||||
|
|
||||||
|
procedure TFpValueDwarfFloat.ReadFloatValue;
|
||||||
|
var
|
||||||
|
Size: TFpDbgValueSize;
|
||||||
|
FullSize: Int64;
|
||||||
|
begin
|
||||||
|
if doneFloat in FEvaluated then
|
||||||
|
exit;
|
||||||
|
Include(FEvaluated, doneFloat);
|
||||||
|
|
||||||
|
FullSize := 0;
|
||||||
|
if GetSize(Size) and IsByteSize(Size) then
|
||||||
|
FullSize := SizeToFullBytes(Size);
|
||||||
|
|
||||||
|
FFloatPrecission := fpDouble;
|
||||||
|
FValue.FValueDouble := 0;
|
||||||
|
case FullSize of
|
||||||
|
{$IF DBG_HAS_EXTENDED}
|
||||||
|
DBG_EXTENDED_SIZE: begin
|
||||||
|
if not Context.ReadExtended(OrdOrDataAddr, Size, FValue.FValueExt) then
|
||||||
|
SetLastError(Context.LastMemError)
|
||||||
|
else
|
||||||
|
FFloatPrecission := fpExtended;
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
SizeOf(double): begin
|
||||||
|
if not Context.ReadDouble(OrdOrDataAddr, Size, FValue.FValueDouble) then begin
|
||||||
|
SetLastError(Context.LastMemError);
|
||||||
|
FValue.FValueDouble := 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
FFloatPrecission := fpDouble;
|
||||||
|
end;
|
||||||
|
SizeOf(Single): begin
|
||||||
|
if not Context.ReadSingle(OrdOrDataAddr, Size, FValue.FValueSingle) then
|
||||||
|
SetLastError(Context.LastMemError)
|
||||||
|
else
|
||||||
|
FFloatPrecission := fpSingle;
|
||||||
|
end;
|
||||||
|
SizeOf(Real48): begin
|
||||||
|
if not Context.ReadDouble(OrdOrDataAddr, Size, FValue.FValueDouble) then begin
|
||||||
|
SetLastError(Context.LastMemError);
|
||||||
|
FValue.FValueDouble := 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
FFloatPrecission := fpDouble;
|
||||||
|
end;
|
||||||
|
else begin
|
||||||
|
SetLastError(CreateError(fpErrorBadFloatSize));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpValueDwarfFloat.GetFieldFlags: TFpValueFieldFlags;
|
function TFpValueDwarfFloat.GetFieldFlags: TFpValueFieldFlags;
|
||||||
begin
|
begin
|
||||||
Result := inherited GetFieldFlags;
|
Result := inherited GetFieldFlags;
|
||||||
Result := Result + [svfFloat] - [svfOrdinal];
|
Result := Result + [svfFloat] - [svfOrdinal];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpValueDwarfFloat.GetAsFloat: Extended;
|
function TFpValueDwarfFloat.GetAsSingle: Single;
|
||||||
var
|
|
||||||
Size: TFpDbgValueSize;
|
|
||||||
begin
|
begin
|
||||||
if doneFloat in FEvaluated then begin
|
DisableFloatExceptions;
|
||||||
Result := FValue;
|
try
|
||||||
exit;
|
ReadFloatValue;
|
||||||
|
case FFloatPrecission of
|
||||||
|
fpSingle: Result := FValue.FValueSingle;
|
||||||
|
fpDouble: Result := FValue.FValueDouble;
|
||||||
|
fpExtended: Result := FValue.FValueExt;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
EnableFloatExceptions;
|
||||||
end;
|
end;
|
||||||
Include(FEvaluated, doneUInt);
|
|
||||||
|
|
||||||
if not GetSize(Size) then
|
|
||||||
Result := 0
|
|
||||||
else
|
|
||||||
if (Size <= 0) or (Size > SizeOf(Result)) then begin
|
|
||||||
Result := 0;
|
|
||||||
SetLastError(CreateError(fpErrorBadFloatSize));
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if not Context.ReadFloat(OrdOrDataAddr, Size, Result) then begin
|
|
||||||
Result := 0; // TODO: error
|
|
||||||
SetLastError(Context.LastMemError);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
FValue := Result;
|
function TFpValueDwarfFloat.GetAsDouble: Double;
|
||||||
|
begin
|
||||||
|
DisableFloatExceptions;
|
||||||
|
try
|
||||||
|
ReadFloatValue;
|
||||||
|
case FFloatPrecission of
|
||||||
|
fpSingle: Result := FValue.FValueSingle;
|
||||||
|
fpDouble: Result := FValue.FValueDouble;
|
||||||
|
fpExtended: Result := FValue.FValueExt;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
EnableFloatExceptions;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpValueDwarfFloat.GetAsExtended: TDbgExtended;
|
||||||
|
begin
|
||||||
|
DisableFloatExceptions;
|
||||||
|
try
|
||||||
|
ReadFloatValue;
|
||||||
|
case FFloatPrecission of
|
||||||
|
fpSingle: Result := FValue.FValueSingle;
|
||||||
|
fpDouble: Result := FValue.FValueDouble;
|
||||||
|
fpExtended: Result := FValue.FValueExt;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
EnableFloatExceptions;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpValueDwarfFloat.GetFloatPrecission: TFpFloatPrecission;
|
||||||
|
begin
|
||||||
|
ReadFloatValue;
|
||||||
|
Result := FFloatPrecission;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpValueDwarfFloat.GetAsFloat: Extended;
|
||||||
|
begin
|
||||||
|
DisableFloatExceptions;
|
||||||
|
try
|
||||||
|
ReadFloatValue;
|
||||||
|
case FFloatPrecission of
|
||||||
|
fpSingle: Result := FValue.FValueSingle;
|
||||||
|
fpDouble: Result := FValue.FValueDouble;
|
||||||
|
fpExtended: Result := FValue.FValueExt;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
EnableFloatExceptions;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFpValueDwarfBoolean }
|
{ TFpValueDwarfBoolean }
|
||||||
|
@ -44,7 +44,7 @@ uses
|
|||||||
Classes, SysUtils, DbgIntfBaseTypes, FpDbgLoader, FpdMemoryTools, FpErrorMessages,
|
Classes, SysUtils, DbgIntfBaseTypes, FpDbgLoader, FpdMemoryTools, FpErrorMessages,
|
||||||
{$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif}, LazClasses, FpDbgCommon,
|
{$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif}, LazClasses, FpDbgCommon,
|
||||||
// Register all image reader classes
|
// Register all image reader classes
|
||||||
FpImgReaderWinPE, FpImgReaderElf, FpImgReaderMacho;
|
FpImgReaderWinPE, FpImgReaderElf, FpImgReaderMacho, LazDebuggerIntfFloatTypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -111,6 +111,8 @@ type
|
|||||||
);
|
);
|
||||||
TFpValueFlags = set of TFpValueFlag;
|
TFpValueFlags = set of TFpValueFlag;
|
||||||
|
|
||||||
|
TFpFloatPrecission = (fpSingle, fpDouble, fpExtended);
|
||||||
|
|
||||||
TFindExportedSymbolsFlag = (fsfIgnoreEnumVals, fsfMatchUnitName);
|
TFindExportedSymbolsFlag = (fsfIgnoreEnumVals, fsfMatchUnitName);
|
||||||
TFindExportedSymbolsFlags = set of TFindExportedSymbolsFlag;
|
TFindExportedSymbolsFlags = set of TFindExportedSymbolsFlag;
|
||||||
|
|
||||||
@ -138,7 +140,11 @@ type
|
|||||||
function GetAsInteger: Int64; virtual;
|
function GetAsInteger: Int64; virtual;
|
||||||
function GetAsString: AnsiString; virtual;
|
function GetAsString: AnsiString; virtual;
|
||||||
function GetAsWideString: WideString; virtual;
|
function GetAsWideString: WideString; virtual;
|
||||||
function GetAsFloat: Extended; virtual;
|
function GetAsSingle: Single; virtual;
|
||||||
|
function GetAsDouble: Double; virtual;
|
||||||
|
function GetAsExtended: TDbgExtended; virtual;
|
||||||
|
function GetFloatPrecission: TFpFloatPrecission; virtual;
|
||||||
|
function GetAsFloat: Extended; virtual; deprecated;
|
||||||
|
|
||||||
procedure SetAsCardinal(AValue: QWord); virtual;
|
procedure SetAsCardinal(AValue: QWord); virtual;
|
||||||
procedure SetAsInteger(AValue: Int64); virtual;
|
procedure SetAsInteger(AValue: Int64); virtual;
|
||||||
@ -198,7 +204,11 @@ type
|
|||||||
property AsBool: Boolean read GetAsBool write SetAsBool;
|
property AsBool: Boolean read GetAsBool write SetAsBool;
|
||||||
property AsString: AnsiString read GetAsString write SetAsString;
|
property AsString: AnsiString read GetAsString write SetAsString;
|
||||||
property AsWideString: WideString read GetAsWideString;
|
property AsWideString: WideString read GetAsWideString;
|
||||||
property AsFloat: Extended read GetAsFloat;
|
property AsSingle: Single read GetAsSingle;
|
||||||
|
property AsDouble: Double read GetAsDouble;
|
||||||
|
property AsExtended: TDbgExtended read GetAsExtended;
|
||||||
|
property FloatPrecission: TFpFloatPrecission read GetFloatPrecission;
|
||||||
|
property AsFloat: Extended read GetAsFloat; deprecated;
|
||||||
|
|
||||||
(* * Address/Size
|
(* * Address/Size
|
||||||
Address of the variable (as returned by the "@" address of operator
|
Address of the variable (as returned by the "@" address of operator
|
||||||
@ -299,7 +309,7 @@ type
|
|||||||
function GetFieldFlags: TFpValueFieldFlags; override;
|
function GetFieldFlags: TFpValueFieldFlags; override;
|
||||||
function GetAsCardinal: QWord; override;
|
function GetAsCardinal: QWord; override;
|
||||||
function GetAsInteger: Int64; override;
|
function GetAsInteger: Int64; override;
|
||||||
function GetAsFloat: Extended; override;
|
function GetAsExtended: TDbgExtended; override;
|
||||||
public
|
public
|
||||||
constructor Create(AValue: QWord; ASigned: Boolean = True);
|
constructor Create(AValue: QWord; ASigned: Boolean = True);
|
||||||
end;
|
end;
|
||||||
@ -360,14 +370,14 @@ type
|
|||||||
|
|
||||||
TFpValueConstFloat = class(TFpValueConstWithType)
|
TFpValueConstFloat = class(TFpValueConstWithType)
|
||||||
private
|
private
|
||||||
FValue: Extended;
|
FValue: TDbgExtended;
|
||||||
protected
|
protected
|
||||||
property Value: Extended read FValue write FValue;
|
property Value: TDbgExtended read FValue write FValue;
|
||||||
function GetKind: TDbgSymbolKind; override;
|
function GetKind: TDbgSymbolKind; override;
|
||||||
function GetFieldFlags: TFpValueFieldFlags; override;
|
function GetFieldFlags: TFpValueFieldFlags; override;
|
||||||
function GetAsFloat: Extended; override;
|
function GetAsExtended: TDbgExtended; override;
|
||||||
public
|
public
|
||||||
constructor Create(AValue: Extended);
|
constructor Create(AValue: TDbgExtended);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFpValueConstBool}
|
{ TFpValueConstBool}
|
||||||
@ -1027,6 +1037,26 @@ begin
|
|||||||
Result := '';
|
Result := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpValue.GetAsSingle: Single;
|
||||||
|
begin
|
||||||
|
Result := GetAsExtended;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpValue.GetAsDouble: Double;
|
||||||
|
begin
|
||||||
|
Result := GetAsExtended;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpValue.GetAsExtended: TDbgExtended;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpValue.GetFloatPrecission: TFpFloatPrecission;
|
||||||
|
begin
|
||||||
|
Result := fpDouble;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpValue.GetDbgSymbol: TFpSymbol;
|
function TFpValue.GetDbgSymbol: TFpSymbol;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
@ -1106,7 +1136,7 @@ end;
|
|||||||
|
|
||||||
function TFpValue.GetAsFloat: Extended;
|
function TFpValue.GetAsFloat: Extended;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := GetAsExtended;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpValue.GetParentTypeInfo: TFpSymbol;
|
function TFpValue.GetParentTypeInfo: TFpSymbol;
|
||||||
@ -1428,7 +1458,7 @@ begin
|
|||||||
{$pop}
|
{$pop}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpValueConstNumber.GetAsFloat: Extended;
|
function TFpValueConstNumber.GetAsExtended: TDbgExtended;
|
||||||
begin
|
begin
|
||||||
Result := GetAsInteger;
|
Result := GetAsInteger;
|
||||||
end;
|
end;
|
||||||
@ -1453,12 +1483,12 @@ begin
|
|||||||
Result := Result + inherited GetFieldFlags;
|
Result := Result + inherited GetFieldFlags;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpValueConstFloat.GetAsFloat: Extended;
|
function TFpValueConstFloat.GetAsExtended: TDbgExtended;
|
||||||
begin
|
begin
|
||||||
Result := FValue;
|
Result := FValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFpValueConstFloat.Create(AValue: Extended);
|
constructor TFpValueConstFloat.Create(AValue: TDbgExtended);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FValue := AValue;
|
FValue := AValue;
|
||||||
|
@ -28,7 +28,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, math, DbgIntfBaseTypes, DbgIntfDebuggerBase, FpErrorMessages, LazClasses,
|
Classes, SysUtils, math, DbgIntfBaseTypes, DbgIntfDebuggerBase, FpErrorMessages, LazClasses,
|
||||||
AVL_Tree, LazDebuggerUtils,
|
AVL_Tree, LazDebuggerUtils, LazDebuggerIntfFloatTypes,
|
||||||
{$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif};
|
{$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif};
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -220,10 +220,16 @@ type
|
|||||||
//function ReadSet (const ALocation: TFpDbgMemLocation; ASize: TFpDbgValueSize;
|
//function ReadSet (const ALocation: TFpDbgMemLocation; ASize: TFpDbgValueSize;
|
||||||
// out AValue: TBytes;
|
// out AValue: TBytes;
|
||||||
// AnOpts: TFpDbgMemReadOptions): Boolean; inline;
|
// AnOpts: TFpDbgMemReadOptions): Boolean; inline;
|
||||||
|
function ReadSingle (const ALocation: TFpDbgMemLocation; ASize: TFpDbgValueSize;
|
||||||
|
out AValue: Single): Boolean; inline;
|
||||||
|
function ReadDouble (const ALocation: TFpDbgMemLocation; ASize: TFpDbgValueSize;
|
||||||
|
out AValue: Double): Boolean; inline;
|
||||||
|
function ReadExtended (const ALocation: TFpDbgMemLocation; ASize: TFpDbgValueSize;
|
||||||
|
out AValue: TDbgExtended): Boolean; inline;
|
||||||
function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: TFpDbgValueSize;
|
function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: TFpDbgValueSize;
|
||||||
out AValue: Extended): Boolean; inline;
|
out AValue: TDbgExtended): Boolean; inline; deprecated;
|
||||||
//function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: TFpDbgValueSize;
|
//function ReadFloat (const ALocation: TFpDbgMemLocation; ASize: TFpDbgValueSize;
|
||||||
// out AValue: Extended;
|
// out AValue: TDbgExtended;
|
||||||
// AnOpts: TFpDbgMemReadOptions): Boolean; inline;
|
// AnOpts: TFpDbgMemReadOptions): Boolean; inline;
|
||||||
|
|
||||||
function ReadString(const ALocation: TFpDbgMemLocation; ALen: Int64; out AValue: RawByteString; AnIgnoreMaxStringLen: boolean = False): Boolean;
|
function ReadString(const ALocation: TFpDbgMemLocation; ALen: Int64; out AValue: RawByteString; AnIgnoreMaxStringLen: boolean = False): Boolean;
|
||||||
@ -1297,12 +1303,30 @@ begin
|
|||||||
Result := MemManager.WriteMemory(rdtSet, ALocation, ASize, @AValue[0], Length(AValue), Self);
|
Result := MemManager.WriteMemory(rdtSet, ALocation, ASize, @AValue[0], Length(AValue), Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpDbgLocationContext.ReadFloat(const ALocation: TFpDbgMemLocation;
|
function TFpDbgLocationContext.ReadSingle(const ALocation: TFpDbgMemLocation;
|
||||||
ASize: TFpDbgValueSize; out AValue: Extended): Boolean;
|
ASize: TFpDbgValueSize; out AValue: Single): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := MemManager.ReadMemory(rdtfloat, ALocation, ASize, @AValue, (SizeOf(AValue)), Self);
|
Result := MemManager.ReadMemory(rdtfloat, ALocation, ASize, @AValue, (SizeOf(AValue)), Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpDbgLocationContext.ReadDouble(const ALocation: TFpDbgMemLocation;
|
||||||
|
ASize: TFpDbgValueSize; out AValue: Double): Boolean;
|
||||||
|
begin
|
||||||
|
Result := MemManager.ReadMemory(rdtfloat, ALocation, ASize, @AValue, (SizeOf(AValue)), Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpDbgLocationContext.ReadExtended(const ALocation: TFpDbgMemLocation;
|
||||||
|
ASize: TFpDbgValueSize; out AValue: TDbgExtended): Boolean;
|
||||||
|
begin
|
||||||
|
Result := MemManager.ReadMemory(rdtfloat, ALocation, ASize, @AValue, Min(SizeOf(AValue), DBG_EXTENDED_SIZE), Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpDbgLocationContext.ReadFloat(const ALocation: TFpDbgMemLocation;
|
||||||
|
ASize: TFpDbgValueSize; out AValue: TDbgExtended): Boolean;
|
||||||
|
begin
|
||||||
|
Result := MemManager.ReadMemory(rdtfloat, ALocation, ASize, @AValue, Min(SizeOf(AValue), DBG_EXTENDED_SIZE), Self);
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDbgLocationContext.ReadString(const ALocation: TFpDbgMemLocation; ALen: Int64; out
|
function TFpDbgLocationContext.ReadString(const ALocation: TFpDbgMemLocation; ALen: Int64; out
|
||||||
AValue: RawByteString; AnIgnoreMaxStringLen: boolean): Boolean;
|
AValue: RawByteString; AnIgnoreMaxStringLen: boolean): Boolean;
|
||||||
begin
|
begin
|
||||||
@ -1469,10 +1493,14 @@ begin
|
|||||||
rdtAddress, rdtSignedInt, rdtUnsignedInt,
|
rdtAddress, rdtSignedInt, rdtUnsignedInt,
|
||||||
rdtEnum, rdtSet: ;
|
rdtEnum, rdtSet: ;
|
||||||
rdtfloat:
|
rdtfloat:
|
||||||
// TODO: reading float from register / or mlfConstant...;
|
Result := IsByteSize(AConvData.SourceSize) and
|
||||||
Result := IsByteSize(AConvData.SourceSize) and // only support exact size for FLOAT
|
( (AConvData.SourceFullSize = AConvData.DestSize) or
|
||||||
(AConvData.DestSize = SizeOf(Extended)) and // only can read to extended... TODO (if need more)
|
( (AConvData.SourceFullSize = SizeOf(Real48)) and
|
||||||
( (AConvData.SourceSize.Size = SizeOf(Extended)) or
|
(AConvData.SourceSize.Size = SizeOf(Double))
|
||||||
|
)
|
||||||
|
) and
|
||||||
|
( (AConvData.SourceSize.Size = DBG_EXTENDED_SIZE) or
|
||||||
|
(AConvData.SourceSize.Size = SizeOf(Extended)) or
|
||||||
(AConvData.SourceSize.Size = SizeOf(Double)) or
|
(AConvData.SourceSize.Size = SizeOf(Double)) or
|
||||||
(AConvData.SourceSize.Size = SizeOf(Single)) or
|
(AConvData.SourceSize.Size = SizeOf(Single)) or
|
||||||
(AConvData.SourceSize.Size = SizeOf(real48))
|
(AConvData.SourceSize.Size = SizeOf(real48))
|
||||||
@ -1535,18 +1563,62 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
rdtfloat: begin
|
rdtfloat: begin
|
||||||
assert((AConvData.DestSize = SizeOf(Extended)));
|
// Currently we have matching sizes, except for real48
|
||||||
if (AConvData.SourceFullSize = SizeOf(Extended)) then
|
|
||||||
//
|
if (AConvData.SourceFullSize = DBG_EXTENDED_SIZE) then begin
|
||||||
|
case AConvData.DestSize of
|
||||||
|
{$IF DBG_HAS_EXTENDED}
|
||||||
|
DBG_EXTENDED_SIZE: PDbgExtended(ADest)^ := PDbgExtended(ADest)^;
|
||||||
|
{$ENDIF}
|
||||||
|
SizeOf(double): PDouble(ADest)^ := PDbgExtended(ADest)^;
|
||||||
|
SizeOf(Single): PSingle(ADest)^ := PDbgExtended(ADest)^;
|
||||||
|
else assert(False, 'TFpDbgMemConvertorLittleEndian.FinishTargetRead: TargetSize not matching');
|
||||||
|
end;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if (AConvData.SourceFullSize = SizeOf(Double)) then
|
if (AConvData.SourceFullSize = SizeOf(Extended)) then begin
|
||||||
PExtended(ADest)^ := PDouble(ADest)^
|
case AConvData.DestSize of
|
||||||
|
{$IF DBG_HAS_EXTENDED}
|
||||||
|
DBG_EXTENDED_SIZE: PDbgExtended(ADest)^ := PExtended(ADest)^;
|
||||||
|
{$ENDIF}
|
||||||
|
SizeOf(double): PDouble(ADest)^ := PExtended(ADest)^;
|
||||||
|
SizeOf(Single): PSingle(ADest)^ := PExtended(ADest)^;
|
||||||
|
else assert(False, 'TFpDbgMemConvertorLittleEndian.FinishTargetRead: TargetSize not matching');
|
||||||
|
end;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if (AConvData.SourceFullSize = SizeOf(real48)) then
|
if (AConvData.SourceFullSize = SizeOf(Double)) then begin
|
||||||
PExtended(ADest)^ := Preal48(ADest)^
|
case AConvData.DestSize of
|
||||||
|
{$IF DBG_HAS_EXTENDED}
|
||||||
|
DBG_EXTENDED_SIZE: PDbgExtended(ADest)^ := PDouble(ADest)^;
|
||||||
|
{$ENDIF}
|
||||||
|
SizeOf(double): PDouble(ADest)^ := PDouble(ADest)^;
|
||||||
|
SizeOf(Single): PSingle(ADest)^ := PDouble(ADest)^;
|
||||||
|
else assert(False, 'TFpDbgMemConvertorLittleEndian.FinishTargetRead: TargetSize not matching');
|
||||||
|
end;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if (AConvData.SourceFullSize = SizeOf(Single)) then
|
if (AConvData.SourceFullSize = SizeOf(Real48)) then begin
|
||||||
PExtended(ADest)^ := PSingle(ADest)^
|
case AConvData.DestSize of
|
||||||
|
{$IF DBG_HAS_EXTENDED}
|
||||||
|
DBG_EXTENDED_SIZE: PDbgExtended(ADest)^ := double(Preal48(ADest)^);
|
||||||
|
{$ENDIF}
|
||||||
|
SizeOf(double): PDouble(ADest)^ := Preal48(ADest)^;
|
||||||
|
//SizeOf(Single): PSingle(ADest)^ := Preal48(ADest)^;
|
||||||
|
else assert(False, 'TFpDbgMemConvertorLittleEndian.FinishTargetRead: TargetSize not matching');
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (AConvData.SourceFullSize = SizeOf(Single)) then begin
|
||||||
|
case AConvData.DestSize of
|
||||||
|
{$IF DBG_HAS_EXTENDED}
|
||||||
|
DBG_EXTENDED_SIZE: PDbgExtended(ADest)^ := PSingle(ADest)^;
|
||||||
|
{$ENDIF}
|
||||||
|
SizeOf(double): PDouble(ADest)^ := PSingle(ADest)^;
|
||||||
|
SizeOf(Single): PSingle(ADest)^ := PSingle(ADest)^;
|
||||||
|
else assert(False, 'TFpDbgMemConvertorLittleEndian.FinishTargetRead: TargetSize not matching');
|
||||||
|
end;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
|
@ -34,7 +34,8 @@ unit FpPascalParser;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, sysutils, math, fgl, DbgIntfBaseTypes, FpDbgInfo, FpdMemoryTools, FpErrorMessages,
|
Classes, sysutils, math, fgl, DbgIntfBaseTypes, LazDebuggerIntfFloatTypes,
|
||||||
|
FpDbgInfo, FpdMemoryTools, FpErrorMessages,
|
||||||
FpDbgDwarf, FpWatchResultData, FpDbgClasses,
|
FpDbgDwarf, FpWatchResultData, FpDbgClasses,
|
||||||
{$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif},
|
{$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif},
|
||||||
LazClasses;
|
LazClasses;
|
||||||
@ -85,8 +86,6 @@ type
|
|||||||
TFpPascalExpressionSharedData = class(TRefCountedObject)
|
TFpPascalExpressionSharedData = class(TRefCountedObject)
|
||||||
// Data used while EVALUATING the expression result
|
// Data used while EVALUATING the expression result
|
||||||
strict private
|
strict private
|
||||||
FFpuMask: TFPUExceptionMask;
|
|
||||||
|
|
||||||
FTextExpression: String;
|
FTextExpression: String;
|
||||||
FScope: TFpDbgSymbolScope;
|
FScope: TFpDbgSymbolScope;
|
||||||
FError: TFpError;
|
FError: TFpError;
|
||||||
@ -4274,8 +4273,7 @@ begin
|
|||||||
inherited Create;
|
inherited Create;
|
||||||
AddReference;
|
AddReference;
|
||||||
|
|
||||||
FFpuMask := GetExceptionMask;
|
DisableFloatExceptions;
|
||||||
SetExceptionMask([low(TFPUExceptionMask)..high(TFPUExceptionMask)]);
|
|
||||||
|
|
||||||
FTextExpression := ATextExpression;
|
FTextExpression := ATextExpression;
|
||||||
FScope := AScope;
|
FScope := AScope;
|
||||||
@ -4285,11 +4283,10 @@ end;
|
|||||||
|
|
||||||
destructor TFpPascalExpressionSharedData.Destroy;
|
destructor TFpPascalExpressionSharedData.Destroy;
|
||||||
begin
|
begin
|
||||||
|
EnableFloatExceptions;
|
||||||
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
FScope.ReleaseReference;
|
FScope.ReleaseReference;
|
||||||
|
|
||||||
ClearExceptions(False);
|
|
||||||
SetExceptionMask(FFpuMask);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpPascalExpressionSharedData.GetDbgSymbolForIdentifier(AnIdent: String;
|
function TFpPascalExpressionSharedData.GetDbgSymbolForIdentifier(AnIdent: String;
|
||||||
|
@ -6,9 +6,12 @@ unit FpWatchResultData;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
// DbgIntf
|
||||||
|
LazDebuggerIntfFloatTypes, DbgIntfBaseTypes, LazDebuggerIntf,
|
||||||
|
//
|
||||||
FpDbgInfo, FpPascalBuilder, FpdMemoryTools, FpErrorMessages, FpDbgDwarf,
|
FpDbgInfo, FpPascalBuilder, FpdMemoryTools, FpErrorMessages, FpDbgDwarf,
|
||||||
FpDbgDwarfDataClasses, DbgIntfBaseTypes, LazClasses, {$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif}, fgl, Math,
|
FpDbgDwarfDataClasses, LazClasses, {$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif}, fgl, Math,
|
||||||
SysUtils, LazDebuggerIntf;
|
SysUtils;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -323,21 +326,13 @@ end;
|
|||||||
|
|
||||||
function TFpWatchResultConvertor.FloatToResData(AnFpValue: TFpValue;
|
function TFpWatchResultConvertor.FloatToResData(AnFpValue: TFpValue;
|
||||||
AnResData: IDbgWatchDataIntf): Boolean;
|
AnResData: IDbgWatchDataIntf): Boolean;
|
||||||
var
|
|
||||||
p: TLzDbgFloatPrecission;
|
|
||||||
s: TFpDbgValueSize;
|
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
|
case AnFpValue.FloatPrecission of
|
||||||
p := dfpSingle;
|
fpSingle: AnResData.CreateFloatValue(AnFpValue.AsSingle);
|
||||||
if AnFpValue.GetSize(s) then begin
|
fpDouble: AnResData.CreateFloatValue(AnFpValue.AsDouble);
|
||||||
if SizeToFullBytes(s) > SizeOf(Double) then
|
fpExtended: AnResData.CreateFloatValue(AnFpValue.AsExtended);
|
||||||
p := dfpExtended
|
|
||||||
else
|
|
||||||
if SizeToFullBytes(s) > SizeOf(Single) then
|
|
||||||
p := dfpDouble
|
|
||||||
end;
|
end;
|
||||||
AnResData.CreateFloatValue(AnFpValue.AsFloat, p);
|
|
||||||
AddTypeNameToResData(AnFpValue, AnResData);
|
AddTypeNameToResData(AnFpValue, AnResData);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -723,10 +723,10 @@ procedure TTestWatches.TestWatchesValue;
|
|||||||
t.Add(AName, p+'Single'+e, weSingle(100.125+n, x+'Single' ));
|
t.Add(AName, p+'Single'+e, weSingle(100.125+n, x+'Single' ));
|
||||||
t.Add(AName, p+'Double'+e, weDouble(1000.125+n, x+'Double' ));
|
t.Add(AName, p+'Double'+e, weDouble(1000.125+n, x+'Double' ));
|
||||||
t.Add(AName, p+'Extended'+e, weFloat(10000.175+n, '' )); // Double ?
|
t.Add(AName, p+'Extended'+e, weFloat(10000.175+n, '' )); // Double ?
|
||||||
{$IFDEF cpu64}
|
// {$IFDEF cpu64}
|
||||||
if Compiler.CpuBitType = cpu32 then // a 64bit debugger does has no 10byte extended type // TODO: check for error
|
// if Compiler.CpuBitType = cpu32 then // a 64bit debugger does has no 10byte extended type // TODO: check for error
|
||||||
t.Tests[-1]^.AddFlag(ehExpectError); // TODO: check error msg
|
// t.Tests[-1]^.AddFlag(ehExpectError); // TODO: check error msg
|
||||||
{$ENDIF}
|
// {$ENDIF}
|
||||||
//t.Add(p+'Comp'+e, weInteger(150.125+n, 'Comp' ));
|
//t.Add(p+'Comp'+e, weInteger(150.125+n, 'Comp' ));
|
||||||
//TODO: currency // integer is wrong, but lets check it
|
//TODO: currency // integer is wrong, but lets check it
|
||||||
t.Add(AName, p+'Currency'+e, weInteger(1251230+n*10000, x+'Currency', SIZE_8 ))
|
t.Add(AName, p+'Currency'+e, weInteger(1251230+n*10000, x+'Currency', SIZE_8 ))
|
||||||
@ -739,10 +739,10 @@ procedure TTestWatches.TestWatchesValue;
|
|||||||
t.Add(AName, p+'Single_2'+e, weSingle(-100.125+n, x+'Single' ));
|
t.Add(AName, p+'Single_2'+e, weSingle(-100.125+n, x+'Single' ));
|
||||||
t.Add(AName, p+'Double_2'+e, weDouble(-1000.125+n, x+'Double' ));
|
t.Add(AName, p+'Double_2'+e, weDouble(-1000.125+n, x+'Double' ));
|
||||||
t.Add(AName, p+'Extended_2'+e, weFloat(-10000.175+n, '' )); // Double ?
|
t.Add(AName, p+'Extended_2'+e, weFloat(-10000.175+n, '' )); // Double ?
|
||||||
{$IFDEF cpu64}
|
// {$IFDEF cpu64}
|
||||||
if Compiler.CpuBitType = cpu32 then // a 64bit debugger does has no 10byte extended type // TODO: check for error
|
// if Compiler.CpuBitType = cpu32 then // a 64bit debugger does has no 10byte extended type // TODO: check for error
|
||||||
t.Tests[-1]^.AddFlag(ehExpectError); // TODO: check error msg
|
// t.Tests[-1]^.AddFlag(ehExpectError); // TODO: check error msg
|
||||||
{$ENDIF}
|
// {$ENDIF}
|
||||||
//t.Add(p+'Comp_2'+e, weFloat(-150.125+n, 'Comp' ));
|
//t.Add(p+'Comp_2'+e, weFloat(-150.125+n, 'Comp' ));
|
||||||
t.Add(AName+'-TODO', p+'Currency_2'+e, weFloat(-125.123+n, x+'Currency' ))^.AddFlag([ehNotImplementedData])
|
t.Add(AName+'-TODO', p+'Currency_2'+e, weFloat(-125.123+n, x+'Currency' ))^.AddFlag([ehNotImplementedData])
|
||||||
.SkipIf(ALoc = tlPointerAny);
|
.SkipIf(ALoc = tlPointerAny);
|
||||||
|
@ -49,6 +49,10 @@ See LCL license for details."/>
|
|||||||
<Filename Value="lazdebuggerutils.pas"/>
|
<Filename Value="lazdebuggerutils.pas"/>
|
||||||
<UnitName Value="LazDebuggerUtils"/>
|
<UnitName Value="LazDebuggerUtils"/>
|
||||||
</Item>
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<Filename Value="lazdebuggerintffloattypes.pas"/>
|
||||||
|
<UnitName Value="LazDebuggerIntfFloatTypes"/>
|
||||||
|
</Item>
|
||||||
</Files>
|
</Files>
|
||||||
<LazDoc Paths="docs"/>
|
<LazDoc Paths="docs"/>
|
||||||
<RequiredPkgs>
|
<RequiredPkgs>
|
||||||
|
@ -21,7 +21,8 @@ unit LazDebuggerIntf;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Types, LazDebuggerValueConverter, LazDebuggerIntfBaseTypes;
|
Classes, SysUtils, Types, LazDebuggerValueConverter, LazDebuggerIntfBaseTypes,
|
||||||
|
LazDebuggerIntfFloatTypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
TDBGState = LazDebuggerIntfBaseTypes.TDBGState deprecated 'Use LazDebuggerIntfBaseTypes.TDBGState';
|
TDBGState = LazDebuggerIntfBaseTypes.TDBGState deprecated 'Use LazDebuggerIntfBaseTypes.TDBGState';
|
||||||
@ -170,7 +171,10 @@ type
|
|||||||
procedure CreateCharValue(ACharValue: QWord; AByteSize: Integer = 0);
|
procedure CreateCharValue(ACharValue: QWord; AByteSize: Integer = 0);
|
||||||
procedure CreateNumValue(ANumValue: QWord; ASigned: Boolean; AByteSize: Integer = 0);
|
procedure CreateNumValue(ANumValue: QWord; ASigned: Boolean; AByteSize: Integer = 0);
|
||||||
procedure CreatePointerValue(AnAddrValue: TDbgPtr);
|
procedure CreatePointerValue(AnAddrValue: TDbgPtr);
|
||||||
procedure CreateFloatValue(AFloatValue: Extended; APrecission: TLzDbgFloatPrecission);
|
procedure CreateFloatValue(AFloatValue: Single);
|
||||||
|
procedure CreateFloatValue(AFloatValue: Double);
|
||||||
|
procedure CreateFloatValue(AFloatValue: TDbgExtended);
|
||||||
|
procedure CreateFloatValue(AFloatValue: Extended; APrecission: TLzDbgFloatPrecission); deprecated;
|
||||||
procedure CreateBoolValue(AnOrdBoolValue: QWord; AByteSize: Integer = 0);
|
procedure CreateBoolValue(AnOrdBoolValue: QWord; AByteSize: Integer = 0);
|
||||||
procedure CreateEnumValue(ANumValue: QWord; AName: String; AByteSize: Integer = 0; AnIsEnumIdent: Boolean = False);
|
procedure CreateEnumValue(ANumValue: QWord; AName: String; AByteSize: Integer = 0; AnIsEnumIdent: Boolean = False);
|
||||||
// //procedure CreateEnumValue(ANumValue: QWord; const ANames: TStringDynArray; const AOrdValues: TIntegerDynArray);
|
// //procedure CreateEnumValue(ANumValue: QWord; const ANames: TStringDynArray; const AOrdValues: TIntegerDynArray);
|
||||||
|
@ -0,0 +1,149 @@
|
|||||||
|
unit LazDebuggerIntfFloatTypes;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$UNDEF HAS_EXTENDED}
|
||||||
|
{$UNDEF HAS_SOFT_EXTENDED}
|
||||||
|
{$UNDEF NO_EXTENDED}
|
||||||
|
|
||||||
|
{$IF sizeof(Extended) = 10}
|
||||||
|
{$DEFINE HAS_EXTENDED}
|
||||||
|
{$ELSE}
|
||||||
|
{$IFDEF windows}
|
||||||
|
{$IF FPC_Fullversion>30202}
|
||||||
|
{$DEFINE HAS_SOFT_EXTENDED}
|
||||||
|
{$ENDIF}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFnDEF HAS_SOFT_EXTENDED}
|
||||||
|
{$DEFINE NO_EXTENDED}
|
||||||
|
{$ENDIF}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
|
||||||
|
uses
|
||||||
|
SysUtils, Math
|
||||||
|
{$ifdef HAS_SOFT_EXTENDED} , ufloatx80, sfpux80 {$endif}
|
||||||
|
;
|
||||||
|
|
||||||
|
const
|
||||||
|
{$ifdef HAS_EXTENDED}
|
||||||
|
DBG_HAS_EXTENDED = True;
|
||||||
|
DBG_EXTENDED_SIZE = 10;
|
||||||
|
{$endif}
|
||||||
|
{$ifdef HAS_SOFT_EXTENDED}
|
||||||
|
DBG_HAS_EXTENDED = True;
|
||||||
|
DBG_EXTENDED_SIZE = 10;
|
||||||
|
{$endif}
|
||||||
|
{$ifdef NO_EXTENDED}
|
||||||
|
DBG_HAS_EXTENDED = False;
|
||||||
|
DBG_EXTENDED_SIZE = 0;
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
procedure DisableFloatExceptions;
|
||||||
|
procedure EnableFloatExceptions;
|
||||||
|
|
||||||
|
type
|
||||||
|
{$ifdef HAS_EXTENDED}
|
||||||
|
TDbgExtended = extended;
|
||||||
|
{$endif}
|
||||||
|
{$ifdef HAS_SOFT_EXTENDED}
|
||||||
|
TDbgExtended = type floatx80;
|
||||||
|
{$endif}
|
||||||
|
{$ifdef NO_EXTENDED}
|
||||||
|
TDbgExtended = type double;
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
PDbgExtended = ^TDbgExtended;
|
||||||
|
|
||||||
|
{$ifdef HAS_SOFT_EXTENDED}
|
||||||
|
operator+ (const f1,f2 : TDbgExtended) : TDbgExtended;inline;
|
||||||
|
operator* (const f1,f2 : TDbgExtended) : TDbgExtended;inline;
|
||||||
|
operator- (const f1,f2 : TDbgExtended) : TDbgExtended;inline;
|
||||||
|
operator/ (const f1,f2 : TDbgExtended) : TDbgExtended;inline;
|
||||||
|
|
||||||
|
operator :=(const source : double) dest : TDbgExtended;inline;
|
||||||
|
operator :=(const source : TDbgExtended) dest : double;inline;
|
||||||
|
operator :=(const source : TDbgExtended) dest : single;inline;
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
var
|
||||||
|
EM: TFPUExceptionMask;
|
||||||
|
{$ifdef HAS_SOFT_EXTENDED}
|
||||||
|
SEM: TFPUExceptionMask;
|
||||||
|
{$endif}
|
||||||
|
FloatExceptionLock: integer = 0;
|
||||||
|
|
||||||
|
|
||||||
|
procedure DisableFloatExceptions;
|
||||||
|
begin
|
||||||
|
if FloatExceptionLock = 0 then begin
|
||||||
|
EM := GetExceptionMask;
|
||||||
|
SetExceptionMask(EM + [exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);
|
||||||
|
{$ifdef HAS_SOFT_EXTENDED}
|
||||||
|
SEM := softfloat_exception_mask;
|
||||||
|
softfloat_exception_mask := SEM + [exInvalidOp, exDenormalized, exZeroDivide,exOverflow, exUnderflow, exPrecision];
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
inc(FloatExceptionLock);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure EnableFloatExceptions;
|
||||||
|
begin
|
||||||
|
dec(FloatExceptionLock);
|
||||||
|
if FloatExceptionLock <= 0 then begin
|
||||||
|
FloatExceptionLock := 0;
|
||||||
|
ClearExceptions(False);
|
||||||
|
SetExceptionMask(EM);
|
||||||
|
{$ifdef HAS_SOFT_EXTENDED}
|
||||||
|
softfloat_exception_mask := SEM;
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ifdef HAS_SOFT_EXTENDED}
|
||||||
|
operator + (const f1, f2: TDbgExtended): TDbgExtended;
|
||||||
|
begin
|
||||||
|
floatx80(Result) := floatx80(f1) + floatx80(f2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
operator * (const f1, f2: TDbgExtended): TDbgExtended;
|
||||||
|
begin
|
||||||
|
floatx80(Result) := floatx80(f1) * floatx80(f2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
operator - (const f1, f2: TDbgExtended): TDbgExtended;
|
||||||
|
begin
|
||||||
|
floatx80(Result) := floatx80(f1) - floatx80(f2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
operator / (const f1, f2: TDbgExtended): TDbgExtended;
|
||||||
|
begin
|
||||||
|
floatx80(Result) := floatx80(f1) / floatx80(f2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
operator := (const source: double)dest: TDbgExtended;
|
||||||
|
begin
|
||||||
|
floatx80(Result) := source;
|
||||||
|
end;
|
||||||
|
|
||||||
|
operator := (const source: TDbgExtended)dest: double;
|
||||||
|
begin
|
||||||
|
Result := floatx80(source);
|
||||||
|
end;
|
||||||
|
|
||||||
|
operator := (const source: TDbgExtended)dest: single;
|
||||||
|
var d: double;
|
||||||
|
begin
|
||||||
|
d := floatx80(source);
|
||||||
|
Result := d;
|
||||||
|
end;
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -9,7 +9,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
LazDebuggerIntf, LazDebuggerTemplate, LazDebuggerIntfBaseTypes, LazDebuggerValueConverter,
|
LazDebuggerIntf, LazDebuggerTemplate, LazDebuggerIntfBaseTypes, LazDebuggerValueConverter,
|
||||||
DbgUtilsTypePatternList, LazDebuggerUtils;
|
DbgUtilsTypePatternList, LazDebuggerUtils, LazDebuggerIntfFloatTypes;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ uses
|
|||||||
// DebuggerIntf
|
// DebuggerIntf
|
||||||
DbgIntfBaseTypes, DbgIntfMiscClasses, DbgIntfDebuggerBase,
|
DbgIntfBaseTypes, DbgIntfMiscClasses, DbgIntfDebuggerBase,
|
||||||
IdeDebuggerWatchValueIntf, LazDebuggerIntf, LazDebuggerIntfBaseTypes,
|
IdeDebuggerWatchValueIntf, LazDebuggerIntf, LazDebuggerIntfBaseTypes,
|
||||||
LazDebuggerValueConverter, LazDebuggerTemplate, IdeDebuggerBase,
|
LazDebuggerValueConverter, LazDebuggerTemplate, LazDebuggerIntfFloatTypes, IdeDebuggerBase,
|
||||||
IdeDebuggerWatchResult, IdeDebuggerOpts, IdeDebuggerBackendValueConv,
|
IdeDebuggerWatchResult, IdeDebuggerOpts, IdeDebuggerBackendValueConv,
|
||||||
IdeDebuggerUtils, IdeDebuggerValueFormatter, IdeDebuggerDisplayFormats, ProjectDebugLink;
|
IdeDebuggerUtils, IdeDebuggerValueFormatter, IdeDebuggerDisplayFormats, ProjectDebugLink;
|
||||||
|
|
||||||
@ -723,19 +723,22 @@ type
|
|||||||
procedure DebugPrint(AText: String);
|
procedure DebugPrint(AText: String);
|
||||||
public
|
public
|
||||||
{%region ***** IDbgWatchDataIntf ***** }
|
{%region ***** IDbgWatchDataIntf ***** }
|
||||||
procedure CreatePrePrinted(AVal: String); virtual; // ATypes: TLzDbgWatchDataTypes);
|
procedure CreatePrePrinted(AVal: String); // ATypes: TLzDbgWatchDataTypes);
|
||||||
procedure CreateString(AVal: String); virtual;// AnEncoding // "pchar data"
|
procedure CreateString(AVal: String); // AnEncoding // "pchar data"
|
||||||
procedure CreateWideString(AVal: WideString); virtual;
|
procedure CreateWideString(AVal: WideString);
|
||||||
procedure CreateCharValue(ACharValue: QWord; AByteSize: Integer = 0); virtual;
|
procedure CreateCharValue(ACharValue: QWord; AByteSize: Integer = 0);
|
||||||
procedure CreateNumValue(ANumValue: QWord; ASigned: Boolean; AByteSize: Integer = 0); virtual;
|
procedure CreateNumValue(ANumValue: QWord; ASigned: Boolean; AByteSize: Integer = 0);
|
||||||
procedure CreatePointerValue(AnAddrValue: TDbgPtr); virtual;
|
procedure CreatePointerValue(AnAddrValue: TDbgPtr);
|
||||||
procedure CreateFloatValue(AFloatValue: Extended; APrecission: TLzDbgFloatPrecission); virtual;
|
procedure CreateFloatValue(AFloatValue: Single);
|
||||||
|
procedure CreateFloatValue(AFloatValue: Double);
|
||||||
|
procedure CreateFloatValue(AFloatValue: TDbgExtended);
|
||||||
|
procedure CreateFloatValue(AFloatValue: Extended; APrecission: TLzDbgFloatPrecission); deprecated;
|
||||||
function CreateProcedure(AVal: TDBGPtr; AnIsFunction: Boolean; ALoc, ADesc: String): IDbgWatchDataIntf;
|
function CreateProcedure(AVal: TDBGPtr; AnIsFunction: Boolean; ALoc, ADesc: String): IDbgWatchDataIntf;
|
||||||
function CreateProcedureRef(AVal: TDBGPtr; AnIsFunction: Boolean; ALoc, ADesc: String): IDbgWatchDataIntf;
|
function CreateProcedureRef(AVal: TDBGPtr; AnIsFunction: Boolean; ALoc, ADesc: String): IDbgWatchDataIntf;
|
||||||
function CreateArrayValue(AnArrayType: TLzDbgArrayType;
|
function CreateArrayValue(AnArrayType: TLzDbgArrayType;
|
||||||
ATotalCount: Integer = 0;
|
ATotalCount: Integer = 0;
|
||||||
ALowIdx: Integer = 0
|
ALowIdx: Integer = 0
|
||||||
): IDbgWatchDataIntf; virtual;
|
): IDbgWatchDataIntf;
|
||||||
procedure CreateBoolValue(AnOrdBoolValue: QWord; AByteSize: Integer = 0);
|
procedure CreateBoolValue(AnOrdBoolValue: QWord; AByteSize: Integer = 0);
|
||||||
procedure CreateEnumValue(ANumValue: QWord; AName: String; AByteSize: Integer = 0; AnIsEnumIdent: Boolean = False);
|
procedure CreateEnumValue(ANumValue: QWord; AName: String; AByteSize: Integer = 0; AnIsEnumIdent: Boolean = False);
|
||||||
// //procedure CreateEnumValue(ANumValue: QWord; const ANames: TStringDynArray; const AOrdValues: TIntegerDynArray);
|
// //procedure CreateEnumValue(ANumValue: QWord; const ANames: TStringDynArray; const AOrdValues: TIntegerDynArray);
|
||||||
@ -750,7 +753,7 @@ type
|
|||||||
function CreateValueHandlerResult(AValueHandler: ILazDbgValueConverterIntf): IDbgWatchDataIntf;
|
function CreateValueHandlerResult(AValueHandler: ILazDbgValueConverterIntf): IDbgWatchDataIntf;
|
||||||
|
|
||||||
procedure CreateMemDump(AVal: RawByteString);
|
procedure CreateMemDump(AVal: RawByteString);
|
||||||
procedure CreateError(AVal: String); virtual;
|
procedure CreateError(AVal: String);
|
||||||
|
|
||||||
function SetPCharShouldBeStringValue: IDbgWatchDataIntf;
|
function SetPCharShouldBeStringValue: IDbgWatchDataIntf;
|
||||||
procedure SetTypeName(ATypeName: String);
|
procedure SetTypeName(ATypeName: String);
|
||||||
@ -3785,11 +3788,44 @@ begin
|
|||||||
AfterDataCreated;
|
AfterDataCreated;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCurrentResData.CreateFloatValue(AFloatValue: Single);
|
||||||
|
begin
|
||||||
|
BeforeCreateValue;
|
||||||
|
assert((FNewResultData=nil) or (FNewResultData is TWatchResultDataSingle), 'TCurrentResData.CreateFloatValue: (FNewResultData=nil) or (FNewResultData.ValueKind=rdkString)');
|
||||||
|
if FNewResultData = nil then
|
||||||
|
FNewResultData := TWatchResultDataSingle.Create(AFloatValue)
|
||||||
|
else
|
||||||
|
TWatchResultDataSingle(FNewResultData).Create(AFloatValue);
|
||||||
|
AfterDataCreated;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCurrentResData.CreateFloatValue(AFloatValue: Double);
|
||||||
|
begin
|
||||||
|
BeforeCreateValue;
|
||||||
|
assert((FNewResultData=nil) or (FNewResultData is TWatchResultDataDouble), 'TCurrentResData.CreateFloatValue: (FNewResultData=nil) or (FNewResultData.ValueKind=rdkString)');
|
||||||
|
if FNewResultData = nil then
|
||||||
|
FNewResultData := TWatchResultDataDouble.Create(AFloatValue)
|
||||||
|
else
|
||||||
|
TWatchResultDataDouble(FNewResultData).Create(AFloatValue);
|
||||||
|
AfterDataCreated;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCurrentResData.CreateFloatValue(AFloatValue: TDbgExtended);
|
||||||
|
begin
|
||||||
|
BeforeCreateValue;
|
||||||
|
assert((FNewResultData=nil) or (FNewResultData is TWatchResultDataExtended), 'TCurrentResData.CreateFloatValue: (FNewResultData=nil) or (FNewResultData.ValueKind=rdkString)');
|
||||||
|
if FNewResultData = nil then
|
||||||
|
FNewResultData := TWatchResultDataExtended.Create(AFloatValue)
|
||||||
|
else
|
||||||
|
TWatchResultDataExtended(FNewResultData).Create(AFloatValue);
|
||||||
|
AfterDataCreated;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCurrentResData.CreateFloatValue(AFloatValue: Extended;
|
procedure TCurrentResData.CreateFloatValue(AFloatValue: Extended;
|
||||||
APrecission: TLzDbgFloatPrecission);
|
APrecission: TLzDbgFloatPrecission);
|
||||||
begin
|
begin
|
||||||
BeforeCreateValue;
|
BeforeCreateValue;
|
||||||
assert((FNewResultData=nil) or (FNewResultData.ValueKind=rdkFloatVal), 'TCurrentResData.CreateFloatValue: (FNewResultData=nil) or (FNewResultData.ValueKind=rdkString)');
|
assert((FNewResultData=nil) or (FNewResultData is TWatchResultDataFloat), 'TCurrentResData.CreateFloatValue: (FNewResultData=nil) or (FNewResultData.ValueKind=rdkString)');
|
||||||
if FNewResultData = nil then
|
if FNewResultData = nil then
|
||||||
FNewResultData := TWatchResultDataFloat.Create(AFloatValue, APrecission)
|
FNewResultData := TWatchResultDataFloat.Create(AFloatValue, APrecission)
|
||||||
else
|
else
|
||||||
|
@ -8,7 +8,8 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, Math, IdeDebuggerWatchResult, IdeDebuggerUtils, IdeDebuggerDisplayFormats,
|
Classes, SysUtils, Math, IdeDebuggerWatchResult, IdeDebuggerUtils, IdeDebuggerDisplayFormats,
|
||||||
IdeDebuggerBase, IdeDebuggerStringConstants, IdeDebuggerValueFormatter, IdeDebuggerWatchResUtils,
|
IdeDebuggerBase, IdeDebuggerStringConstants, IdeDebuggerValueFormatter, IdeDebuggerWatchResUtils,
|
||||||
LazDebuggerIntf, LazUTF8, IdeDebuggerWatchValueIntf, StrUtils, LazDebuggerUtils;
|
LazDebuggerIntf, LazUTF8, IdeDebuggerWatchValueIntf, StrUtils, LazDebuggerUtils,
|
||||||
|
LazDebuggerIntfFloatTypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -1542,6 +1543,8 @@ function TWatchResultPrinter.PrintWatchValue(AResValue: TWatchResultData;
|
|||||||
var
|
var
|
||||||
Res: TStringBuilderPart;
|
Res: TStringBuilderPart;
|
||||||
begin
|
begin
|
||||||
|
DisableFloatExceptions;
|
||||||
|
try
|
||||||
FNextValueFormatter := nil;
|
FNextValueFormatter := nil;
|
||||||
if FOnlyValueFormatter <> nil then
|
if FOnlyValueFormatter <> nil then
|
||||||
FDefaultValueFormatter := FOnlyValueFormatter
|
FDefaultValueFormatter := FOnlyValueFormatter
|
||||||
@ -1568,6 +1571,9 @@ begin
|
|||||||
Res := PrintWatchValueEx(AResValue, ADispFormat, -1, FWatchedVarName);
|
Res := PrintWatchValueEx(AResValue, ADispFormat, -1, FWatchedVarName);
|
||||||
Result := Res.GetFullString;
|
Result := Res.GetFullString;
|
||||||
Res.FreeAll;
|
Res.FreeAll;
|
||||||
|
finally
|
||||||
|
EnableFloatExceptions;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TWatchResultPrinter.PrintWatchValueIntf(AResValue: IWatchResultDataIntf;
|
function TWatchResultPrinter.PrintWatchValueIntf(AResValue: IWatchResultDataIntf;
|
||||||
|
@ -8,7 +8,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, Types,
|
Classes, SysUtils, Types,
|
||||||
// LazDebuggerIntf
|
// LazDebuggerIntf
|
||||||
LazDebuggerIntf, LazDebuggerIntfBaseTypes,
|
LazDebuggerIntf, LazDebuggerIntfBaseTypes, LazDebuggerIntfFloatTypes,
|
||||||
// IdeIntf
|
// IdeIntf
|
||||||
IdeDebuggerWatchValueIntf,
|
IdeDebuggerWatchValueIntf,
|
||||||
// LclBase
|
// LclBase
|
||||||
@ -33,6 +33,9 @@ type
|
|||||||
function GetAsWideString: WideString; inline;
|
function GetAsWideString: WideString; inline;
|
||||||
function GetAsQWord: QWord; inline;
|
function GetAsQWord: QWord; inline;
|
||||||
function GetAsInt64: Int64; inline;
|
function GetAsInt64: Int64; inline;
|
||||||
|
function GetAsSingle: Single; inline;
|
||||||
|
function GetAsDouble: Double; inline;
|
||||||
|
function GetAsExtended: TDbgExtended; inline;
|
||||||
function GetAsFloat: Extended; inline;
|
function GetAsFloat: Extended; inline;
|
||||||
function GetByteSize: Integer; inline; // Int, Enum
|
function GetByteSize: Integer; inline; // Int, Enum
|
||||||
function GetFloatPrecission: TLzDbgFloatPrecission; inline;
|
function GetFloatPrecission: TLzDbgFloatPrecission; inline;
|
||||||
@ -231,15 +234,25 @@ type
|
|||||||
|
|
||||||
{ TWatchResultValueFloat }
|
{ TWatchResultValueFloat }
|
||||||
|
|
||||||
TWatchResultValueFloat = object(TWatchResultValue)
|
{ TWatchResultValueFloatBase }
|
||||||
|
|
||||||
|
{ TGenericWatchResultValueFloat }
|
||||||
|
|
||||||
|
generic TGenericWatchResultValueFloat<TFLOAT> = object(TWatchResultValue)
|
||||||
protected const
|
protected const
|
||||||
VKind = rdkFloatVal;
|
VKind = rdkFloatVal;
|
||||||
private
|
private
|
||||||
FFloatValue: Extended;
|
FFloatValue: TFLOAT;
|
||||||
protected
|
protected
|
||||||
function GetIsDephtlessData: Boolean; inline;
|
function GetIsDephtlessData: Boolean; inline;
|
||||||
property GetAsFloat: Extended read FFloatValue;
|
function GetAsSingle: Single; inline;
|
||||||
|
function GetAsDouble: Double; inline;
|
||||||
|
function GetAsExtended: TDbgExtended; inline;
|
||||||
|
function GetAsFloat: Extended;
|
||||||
function GetAsString: RawByteString; inline;
|
function GetAsString: RawByteString; inline;
|
||||||
|
procedure SetFromString(s: string); inline;
|
||||||
|
|
||||||
|
(* Once Saved/Loaded precission may be lowered *)
|
||||||
procedure LoadDataFromXMLConfig(const AConfig: TXMLConfig; const APath: string;
|
procedure LoadDataFromXMLConfig(const AConfig: TXMLConfig; const APath: string;
|
||||||
const AnEntryTemplate: TWatchResultData;
|
const AnEntryTemplate: TWatchResultData;
|
||||||
var AnOverrideTemplate: TOverrideTemplateData;
|
var AnOverrideTemplate: TOverrideTemplateData;
|
||||||
@ -247,6 +260,31 @@ type
|
|||||||
procedure SaveDataToXMLConfig(const AConfig: TXMLConfig; const APath: string; AnAsProto: Boolean);
|
procedure SaveDataToXMLConfig(const AConfig: TXMLConfig; const APath: string; AnAsProto: Boolean);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultValueFloat }
|
||||||
|
|
||||||
|
TWatchResultValueFloat = specialize TGenericWatchResultValueFloat<Extended>;
|
||||||
|
|
||||||
|
{ TWatchResultValueSingle }
|
||||||
|
|
||||||
|
TWatchResultValueSingle = object(specialize TGenericWatchResultValueFloat<Single>)
|
||||||
|
protected
|
||||||
|
function GetFloatPrecission: TLzDbgFloatPrecission; inline;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultValueDouble }
|
||||||
|
|
||||||
|
TWatchResultValueDouble = object(specialize TGenericWatchResultValueFloat<Double>)
|
||||||
|
protected
|
||||||
|
function GetFloatPrecission: TLzDbgFloatPrecission; inline;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultValueExtended }
|
||||||
|
|
||||||
|
TWatchResultValueExtended = object(specialize TGenericWatchResultValueFloat<TDbgExtended>)
|
||||||
|
protected
|
||||||
|
function GetFloatPrecission: TLzDbgFloatPrecission; inline;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TWatchResultTypeFloat }
|
{ TWatchResultTypeFloat }
|
||||||
|
|
||||||
TWatchResultTypeFloat = object(TWatchResultValue)
|
TWatchResultTypeFloat = object(TWatchResultValue)
|
||||||
@ -765,7 +803,10 @@ type
|
|||||||
function GetAsWideString: WideString; virtual; abstract;
|
function GetAsWideString: WideString; virtual; abstract;
|
||||||
function GetAsQWord: QWord; virtual; abstract;
|
function GetAsQWord: QWord; virtual; abstract;
|
||||||
function GetAsInt64: Int64; virtual; abstract;
|
function GetAsInt64: Int64; virtual; abstract;
|
||||||
function GetAsFloat: Extended; virtual; abstract;
|
function GetAsSingle: Single; virtual; abstract;
|
||||||
|
function GetAsDouble: Double; virtual; abstract;
|
||||||
|
function GetAsExtended: TDbgExtended; virtual; abstract;
|
||||||
|
function GetAsFloat: Extended; virtual; abstract; deprecated;
|
||||||
|
|
||||||
function GetByteSize: Integer; virtual; abstract;
|
function GetByteSize: Integer; virtual; abstract;
|
||||||
function GetFloatPrecission: TLzDbgFloatPrecission; virtual; abstract;
|
function GetFloatPrecission: TLzDbgFloatPrecission; virtual; abstract;
|
||||||
@ -830,7 +871,10 @@ type
|
|||||||
property AsWideString: WideString read GetAsWideString;
|
property AsWideString: WideString read GetAsWideString;
|
||||||
property AsQWord: QWord read GetAsQWord;
|
property AsQWord: QWord read GetAsQWord;
|
||||||
property AsInt64: Int64 read GetAsInt64;
|
property AsInt64: Int64 read GetAsInt64;
|
||||||
property AsFloat: Extended read GetAsFloat;
|
property AsSingle: Single read GetAsSingle;
|
||||||
|
property AsDouble: Double read GetAsDouble;
|
||||||
|
property AsExtended: TDbgExtended read GetAsExtended;
|
||||||
|
property AsFloat: Extended read GetAsFloat; deprecated;
|
||||||
|
|
||||||
property ByteSize: Integer read GetByteSize;
|
property ByteSize: Integer read GetByteSize;
|
||||||
property FloatPrecission: TLzDbgFloatPrecission read GetFloatPrecission;
|
property FloatPrecission: TLzDbgFloatPrecission read GetFloatPrecission;
|
||||||
@ -1018,7 +1062,10 @@ type
|
|||||||
function GetAsWideString: WideString; override;
|
function GetAsWideString: WideString; override;
|
||||||
function GetAsQWord: QWord; override;
|
function GetAsQWord: QWord; override;
|
||||||
function GetAsInt64: Int64; override;
|
function GetAsInt64: Int64; override;
|
||||||
function GetAsFloat: Extended; override;
|
function GetAsSingle: Single; override;
|
||||||
|
function GetAsDouble: Double; override;
|
||||||
|
function GetAsExtended: TDbgExtended; override;
|
||||||
|
function GetAsFloat: Extended; override; deprecated;
|
||||||
|
|
||||||
function GetByteSize: Integer; override;
|
function GetByteSize: Integer; override;
|
||||||
function GetFloatPrecission: TLzDbgFloatPrecission; override;
|
function GetFloatPrecission: TLzDbgFloatPrecission; override;
|
||||||
@ -1207,6 +1254,35 @@ type
|
|||||||
constructor Create(AFloatValue: Extended; APrecission: TLzDbgFloatPrecission);
|
constructor Create(AFloatValue: Extended; APrecission: TLzDbgFloatPrecission);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultDataFloatSized }
|
||||||
|
|
||||||
|
//generic TWatchResultDataFloatSized<TFLOAT> = class(specialize TGenericWatchResultData<specialize TGenericWatchResultValueFloat<TFLOAT> >)
|
||||||
|
generic TWatchResultDataFloatSized<_DATA> = class(specialize TGenericWatchResultData<_DATA>)
|
||||||
|
private
|
||||||
|
function GetClassID: TWatchResultDataClassID; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultDataSingle }
|
||||||
|
|
||||||
|
TWatchResultDataSingle = class(specialize TWatchResultDataFloatSized<TWatchResultValueSingle>)
|
||||||
|
public
|
||||||
|
constructor Create(AFloatValue: Single);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultDataDouble }
|
||||||
|
|
||||||
|
TWatchResultDataDouble = class(specialize TWatchResultDataFloatSized<TWatchResultValueDouble>)
|
||||||
|
public
|
||||||
|
constructor Create(AFloatValue: Double);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultDataExtended }
|
||||||
|
|
||||||
|
TWatchResultDataExtended = class(specialize TWatchResultDataFloatSized<TWatchResultValueExtended>)
|
||||||
|
public
|
||||||
|
constructor Create(AFloatValue: TDbgExtended);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TWatchResultDataBoolean }
|
{ TWatchResultDataBoolean }
|
||||||
|
|
||||||
TWatchResultDataBoolean = class(specialize TGenericWatchResultDataSizedNum<TWatchResultValueBoolean>)
|
TWatchResultDataBoolean = class(specialize TGenericWatchResultDataSizedNum<TWatchResultValueBoolean>)
|
||||||
@ -1591,6 +1667,12 @@ type
|
|||||||
|
|
||||||
function dbgs(AResKind: TWatchResultDataKind): String; overload;
|
function dbgs(AResKind: TWatchResultDataKind): String; overload;
|
||||||
|
|
||||||
|
|
||||||
|
function FloatToStr(Value: TDbgExtended; const FormatSettings: TFormatSettings): String; overload;
|
||||||
|
var
|
||||||
|
_TGenericWatchResultValueFloat_FPointSettings: TFormatSettings; // generics force this to be in interface
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function dbgs(AResKind: TWatchResultDataKind): String;
|
function dbgs(AResKind: TWatchResultDataKind): String;
|
||||||
@ -1655,6 +1737,21 @@ begin
|
|||||||
Result := 0;
|
Result := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TWatchResultValue.GetAsSingle: Single;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TWatchResultValue.GetAsDouble: Double;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TWatchResultValue.GetAsExtended: TDbgExtended;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
function TWatchResultValue.GetAsFloat: Extended;
|
function TWatchResultValue.GetAsFloat: Extended;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := 0;
|
||||||
@ -2038,32 +2135,91 @@ begin
|
|||||||
AConfig.DeletePath(APath + 'Deref');
|
AConfig.DeletePath(APath + 'Deref');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TWatchResultValueFloat }
|
{ TGenericWatchResultValueFloat }
|
||||||
|
|
||||||
function TWatchResultValueFloat.GetIsDephtlessData: Boolean;
|
function FloatToStr(Value: TDbgExtended; const FormatSettings: TFormatSettings): String; overload;
|
||||||
|
begin
|
||||||
|
{$IF DBG_HAS_EXTENDED}
|
||||||
|
Result := SysUtils.FloatToStr(double(Value), FormatSettings);
|
||||||
|
{$ELSE}
|
||||||
|
Result := SysUtils.FloatToStr(Value, FormatSettings);
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericWatchResultValueFloat.GetIsDephtlessData: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TWatchResultValueFloat.GetAsString: RawByteString;
|
function TGenericWatchResultValueFloat.GetAsSingle: Single;
|
||||||
begin
|
begin
|
||||||
Result := FloatToStr(FFloatValue);
|
Result := FFloatValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TWatchResultValueFloat.LoadDataFromXMLConfig(
|
function TGenericWatchResultValueFloat.GetAsDouble: Double;
|
||||||
const AConfig: TXMLConfig; const APath: string;
|
begin
|
||||||
const AnEntryTemplate: TWatchResultData;
|
Result := FFloatValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericWatchResultValueFloat.GetAsExtended: TDbgExtended;
|
||||||
|
begin
|
||||||
|
Result := FFloatValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericWatchResultValueFloat.GetAsFloat: Extended;
|
||||||
|
begin
|
||||||
|
Result := FFloatValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericWatchResultValueFloat.GetAsString: RawByteString;
|
||||||
|
begin
|
||||||
|
DisableFloatExceptions;
|
||||||
|
try
|
||||||
|
Result := FloatToStr(FFloatValue, _TGenericWatchResultValueFloat_FPointSettings);
|
||||||
|
finally
|
||||||
|
EnableFloatExceptions;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericWatchResultValueFloat.SetFromString(s: string);
|
||||||
|
begin
|
||||||
|
FFloatValue := StrToFloatDef(s, 0, _TGenericWatchResultValueFloat_FPointSettings);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGenericWatchResultValueFloat.LoadDataFromXMLConfig(const AConfig: TXMLConfig;
|
||||||
|
const APath: string; const AnEntryTemplate: TWatchResultData;
|
||||||
var AnOverrideTemplate: TOverrideTemplateData; AnAsProto: Boolean);
|
var AnOverrideTemplate: TOverrideTemplateData; AnAsProto: Boolean);
|
||||||
begin
|
begin
|
||||||
inherited LoadDataFromXMLConfig(AConfig, APath, AnEntryTemplate, AnOverrideTemplate, AnAsProto);
|
inherited LoadDataFromXMLConfig(AConfig, APath, AnEntryTemplate, AnOverrideTemplate, AnAsProto);
|
||||||
FFloatValue := AConfig.GetExtendedValue(APath + 'Value', 0);
|
SetFromString(AConfig.GetValue(APath + 'Value', '0'));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TWatchResultValueFloat.SaveDataToXMLConfig(const AConfig: TXMLConfig;
|
procedure TGenericWatchResultValueFloat.SaveDataToXMLConfig(const AConfig: TXMLConfig;
|
||||||
const APath: string; AnAsProto: Boolean);
|
const APath: string; AnAsProto: Boolean);
|
||||||
begin
|
begin
|
||||||
inherited SaveDataToXMLConfig(AConfig, APath, AnAsProto);
|
inherited SaveDataToXMLConfig(AConfig, APath, AnAsProto);
|
||||||
AConfig.SetExtendedValue(APath + 'Value', FFloatValue);
|
AConfig.SetValue(APath + 'Value', GetAsString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultValueSingle }
|
||||||
|
|
||||||
|
function TWatchResultValueSingle.GetFloatPrecission: TLzDbgFloatPrecission;
|
||||||
|
begin
|
||||||
|
Result := dfpSingle; //, dfpDouble, dfpExtended
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultValueDouble }
|
||||||
|
|
||||||
|
function TWatchResultValueDouble.GetFloatPrecission: TLzDbgFloatPrecission;
|
||||||
|
begin
|
||||||
|
Result := dfpDouble;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultValueExtended }
|
||||||
|
|
||||||
|
function TWatchResultValueExtended.GetFloatPrecission: TLzDbgFloatPrecission;
|
||||||
|
begin
|
||||||
|
Result := dfpExtended;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TWatchResultTypeFloat }
|
{ TWatchResultTypeFloat }
|
||||||
@ -3432,6 +3588,21 @@ begin
|
|||||||
Result := FData.GetAsInt64;
|
Result := FData.GetAsInt64;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TGenericWatchResultData.GetAsSingle: Single;
|
||||||
|
begin
|
||||||
|
Result := FData.GetAsSingle;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericWatchResultData.GetAsDouble: Double;
|
||||||
|
begin
|
||||||
|
Result := FData.GetAsDouble;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGenericWatchResultData.GetAsExtended: TDbgExtended;
|
||||||
|
begin
|
||||||
|
Result := FData.GetAsExtended;
|
||||||
|
end;
|
||||||
|
|
||||||
function TGenericWatchResultData.GetAsFloat: Extended;
|
function TGenericWatchResultData.GetAsFloat: Extended;
|
||||||
begin
|
begin
|
||||||
Result := FData.GetAsFloat;
|
Result := FData.GetAsFloat;
|
||||||
@ -3986,6 +4157,34 @@ begin
|
|||||||
FType.FFloatPrecission := APrecission;
|
FType.FFloatPrecission := APrecission;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultDataFloatSized }
|
||||||
|
|
||||||
|
function TWatchResultDataFloatSized.GetClassID: TWatchResultDataClassID;
|
||||||
|
begin
|
||||||
|
Result := wdFloat;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultDataSingle }
|
||||||
|
|
||||||
|
constructor TWatchResultDataSingle.Create(AFloatValue: Single);
|
||||||
|
begin
|
||||||
|
FData.FFloatValue := AFloatValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultDataDouble }
|
||||||
|
|
||||||
|
constructor TWatchResultDataDouble.Create(AFloatValue: Double);
|
||||||
|
begin
|
||||||
|
FData.FFloatValue := AFloatValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TWatchResultDataExtended }
|
||||||
|
|
||||||
|
constructor TWatchResultDataExtended.Create(AFloatValue: TDbgExtended);
|
||||||
|
begin
|
||||||
|
FData.FFloatValue := AFloatValue;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TWatchResultDataBoolean }
|
{ TWatchResultDataBoolean }
|
||||||
|
|
||||||
function TWatchResultDataBoolean.GetClassID: TWatchResultDataClassID;
|
function TWatchResultDataBoolean.GetClassID: TWatchResultDataClassID;
|
||||||
@ -5128,5 +5327,10 @@ begin
|
|||||||
FData.FText := APrintedVal;
|
FData.FText := APrintedVal;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
_TGenericWatchResultValueFloat_FPointSettings := DefaultFormatSettings;
|
||||||
|
_TGenericWatchResultValueFloat_FPointSettings.DecimalSeparator := '.';
|
||||||
|
_TGenericWatchResultValueFloat_FPointSettings.ThousandSeparator := ',';
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user