fix(debug-opdf): emit recPrimitive for Double and Single
Float-typed variables (Double, Single) were invisible in pdr — locals, print, gl and every other inspection command failed for floats while integers, strings, classes and records-of-int-and-string worked. The OPDF emitter never produced a recPrimitive for tyDouble/tySingle: EmitTypeDesc did not dispatch the float kinds, so a float variable's GlobalVar/LocalVar record referenced a TypeID with no corresponding type record, and pdr could not resolve the type to read the value. EmitTypeDesc now routes tyDouble/tySingle to EmitPrimitive, which emits the record with SizeInBytes (8/4), IsSigned=1, and a new SubKind=SK_FLOAT (4). The pdr side already handled this fully: the adapter maps SubKind skFloat to Category tcFloat and TFloatEvaluator reads the IEEE 754 value by size — it was only waiting for the compiler to emit the record. Verified end to end with pdr: a global, a local, and a Double record field all print their values (d = 3.14159, s = 2.5, pt.Z = 9.81), and locals lists them. IR tests assert the Double/Single recPrimitive carries SubKind=4 and the correct size.
This commit is contained in:
parent
2759a27329
commit
c3ed2c89d6
|
|
@ -140,6 +140,8 @@ const
|
||||||
|
|
||||||
SK_INTEGER = 0;
|
SK_INTEGER = 0;
|
||||||
SK_BOOLEAN = 1;
|
SK_BOOLEAN = 1;
|
||||||
|
{ SK_CHAR = 2; SK_WIDECHAR = 3; — reserved by the OPDF spec, not emitted yet }
|
||||||
|
SK_FLOAT = 4; { Single, Double — pdr renders via TFloatEvaluator }
|
||||||
|
|
||||||
LOC_RBP = 1;
|
LOC_RBP = 1;
|
||||||
LOC_RBP_INDIRECT = 3; { frame slot holds the value's address }
|
LOC_RBP_INDIRECT = 3; { frame slot holds the value's address }
|
||||||
|
|
@ -369,7 +371,8 @@ begin
|
||||||
if HasBeenEmitted(CName) then Exit;
|
if HasBeenEmitted(CName) then Exit;
|
||||||
case AType.Kind of
|
case AType.Kind of
|
||||||
tyInteger, tyInt64, tyUInt32, tyUInt64,
|
tyInteger, tyInt64, tyUInt32, tyUInt64,
|
||||||
tySmallInt, tyWord, tyByte, tyBoolean:
|
tySmallInt, tyWord, tyByte, tyBoolean,
|
||||||
|
tyDouble, tySingle:
|
||||||
EmitPrimitive(AType);
|
EmitPrimitive(AType);
|
||||||
tyString:
|
tyString:
|
||||||
EmitUtf8Str();
|
EmitUtf8Str();
|
||||||
|
|
@ -407,6 +410,10 @@ begin
|
||||||
tyBoolean: begin SubKind := SK_BOOLEAN; IsSigned := 0; end;
|
tyBoolean: begin SubKind := SK_BOOLEAN; IsSigned := 0; end;
|
||||||
tyInt64, tyInteger, tySmallInt:
|
tyInt64, tyInteger, tySmallInt:
|
||||||
begin SubKind := SK_INTEGER; IsSigned := 1; end;
|
begin SubKind := SK_INTEGER; IsSigned := 1; end;
|
||||||
|
tyDouble, tySingle:
|
||||||
|
{ Single (4B) / Double (8B) — pdr keys off SubKind=skFloat
|
||||||
|
and reads the IEEE 754 value by SizeInBytes. }
|
||||||
|
begin SubKind := SK_FLOAT; IsSigned := 1; end;
|
||||||
else
|
else
|
||||||
SubKind := SK_INTEGER; IsSigned := 0;
|
SubKind := SK_INTEGER; IsSigned := 0;
|
||||||
end;
|
end;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ type
|
||||||
procedure TestOPDF_Primitive_Integer;
|
procedure TestOPDF_Primitive_Integer;
|
||||||
procedure TestOPDF_Primitive_Boolean;
|
procedure TestOPDF_Primitive_Boolean;
|
||||||
procedure TestOPDF_Primitive_Int64;
|
procedure TestOPDF_Primitive_Int64;
|
||||||
|
procedure TestOPDF_Primitive_Double_SubKindFloat;
|
||||||
|
procedure TestOPDF_Primitive_Single_SubKindFloat;
|
||||||
procedure TestOPDF_AnsiStr_Record;
|
procedure TestOPDF_AnsiStr_Record;
|
||||||
procedure TestOPDF_GlobalVar_QuadLabel;
|
procedure TestOPDF_GlobalVar_QuadLabel;
|
||||||
procedure TestOPDF_GlobalVar_RecType;
|
procedure TestOPDF_GlobalVar_RecType;
|
||||||
|
|
@ -175,6 +177,44 @@ begin
|
||||||
AssertTrue('recPrimitive Int64 present', Contains(IR, '# recPrimitive: Int64'));
|
AssertTrue('recPrimitive Int64 present', Contains(IR, '# recPrimitive: Int64'));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TOPDFTests.TestOPDF_Primitive_Double_SubKindFloat;
|
||||||
|
{ Regression: float types emitted NO recPrimitive at all, so a Double/Single
|
||||||
|
variable referenced a TypeID with no type record and pdr could not print it
|
||||||
|
(locals/print/gl all failed for floats). A Double must now emit a recPrimitive
|
||||||
|
with SubKind=SK_FLOAT(4) and SizeInBytes=8 so pdr's TFloatEvaluator
|
||||||
|
(Category=tcFloat, keyed off SubKind in [skFloat, skCurrency]) renders it. }
|
||||||
|
var
|
||||||
|
IR: string;
|
||||||
|
P: Integer;
|
||||||
|
begin
|
||||||
|
IR := GenOPDF('program P; var D: Double; begin D := 1.5 end.');
|
||||||
|
AssertTrue('recPrimitive Double comment', Contains(IR, '# recPrimitive: Double'));
|
||||||
|
AssertTrue('Double name emitted', Contains(IR, '.ascii "Double"'));
|
||||||
|
P := Pos('# recPrimitive: Double', IR);
|
||||||
|
AssertTrue('Double recPrimitive present', P >= 0);
|
||||||
|
{ SubKind must be SK_FLOAT (4) and size 8, in the Double record's payload. }
|
||||||
|
AssertTrue('Double SubKind = 4 (skFloat)',
|
||||||
|
Pos('.byte 4 # SubKind', Copy(IR, P, 220)) >= 0);
|
||||||
|
AssertTrue('Double SizeInBytes = 8',
|
||||||
|
Pos('.byte 8 # SizeInBytes', Copy(IR, P, 220)) >= 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TOPDFTests.TestOPDF_Primitive_Single_SubKindFloat;
|
||||||
|
{ Single is the 4-byte float counterpart; same recPrimitive shape, size 4. }
|
||||||
|
var
|
||||||
|
IR: string;
|
||||||
|
P: Integer;
|
||||||
|
begin
|
||||||
|
IR := GenOPDF('program P; var S: Single; begin S := 1.5 end.');
|
||||||
|
AssertTrue('recPrimitive Single comment', Contains(IR, '# recPrimitive: Single'));
|
||||||
|
P := Pos('# recPrimitive: Single', IR);
|
||||||
|
AssertTrue('Single recPrimitive present', P >= 0);
|
||||||
|
AssertTrue('Single SubKind = 4 (skFloat)',
|
||||||
|
Pos('.byte 4 # SubKind', Copy(IR, P, 220)) >= 0);
|
||||||
|
AssertTrue('Single SizeInBytes = 4',
|
||||||
|
Pos('.byte 4 # SizeInBytes', Copy(IR, P, 220)) >= 0);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TOPDFTests.TestOPDF_AnsiStr_Record;
|
procedure TOPDFTests.TestOPDF_AnsiStr_Record;
|
||||||
var
|
var
|
||||||
IR: string;
|
IR: string;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue