-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy patharray_pointer_index_offset_semantic.dpr
More file actions
85 lines (73 loc) · 2.07 KB
/
Copy patharray_pointer_index_offset_semantic.dpr
File metadata and controls
85 lines (73 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
program array_pointer_index_offset_semantic;
{$ifdef FPC}
{$mode delphi}
{$endif}
uses
{$ifdef FPC}
mormot.core.fpcx64mm,
{$ifdef UNIX}cthreads,cwstring,{$endif UNIX}
{$endif}
SysUtils;
type
TByteArray = array[0 .. 255] of Byte;
PByteArray = ^TByteArray;
TWordArray = array[0 .. 255] of Word;
PWordArray = ^TWordArray;
function ByteAddress(P: Pointer): Pointer; inline;
begin
Result := @PByteArray(P)[PByte(P + 1)^ + 2];
end;
function ByteAddressConstLeft(P: Pointer): Pointer; inline;
begin
Result := @PByteArray(P)[2 + PByte(P + 1)^];
end;
function ByteAddressSubtract(P: Pointer): Pointer; inline;
begin
Result := @PByteArray(P)[PByte(P + 1)^ - (-2)];
end;
function ByteAddressFromOffsetBase(P: Pointer): Pointer; inline;
begin
Result := @PByteArray(P + 3)[PByte(P + 1)^ + 2];
end;
function WordAddress(P: Pointer): Pointer; inline;
begin
Result := @PWordArray(P)[PByte(P + 1)^ + 2];
end;
{$push}{$Q-}
function CardinalAddress(Base: PtrUInt; Index: Cardinal): PtrUInt;
{$ifdef FPC}noinline;{$endif}
begin
Inc(Index, 2);
Result := Base + Index;
end;
{$pop}
function UInt64Address(Base: PtrUInt; Index: UInt64): PtrUInt;
{$ifdef FPC}noinline;{$endif}
begin
Inc(Index, 2);
Result := Base + Index;
end;
procedure CheckOffset(P, Actual: Pointer; Expected: PtrUInt; Code: Byte);
begin
if PtrUInt(Actual) - PtrUInt(P) <> Expected then
Halt(Code);
end;
var
Buffer: array[0 .. 511] of Byte;
I: Integer;
begin
for I := 0 to 200 do
begin
Buffer[1] := I;
CheckOffset(@Buffer, ByteAddress(@Buffer), PtrUInt(I + 2), 1);
CheckOffset(@Buffer, ByteAddressConstLeft(@Buffer), PtrUInt(I + 2), 2);
CheckOffset(@Buffer, ByteAddressSubtract(@Buffer), PtrUInt(I + 2), 3);
CheckOffset(@Buffer, ByteAddressFromOffsetBase(@Buffer), PtrUInt(I + 5), 4);
CheckOffset(@Buffer, WordAddress(@Buffer), PtrUInt((I + 2) * 2), 5);
end;
CheckOffset(@Buffer,
Pointer(CardinalAddress(PtrUInt(@Buffer), High(Cardinal))), 1, 6);
CheckOffset(@Buffer,
Pointer(UInt64Address(PtrUInt(@Buffer), 40)), 42, 7);
WriteLn('ARRAY_POINTER_INDEX_OFFSET_OK');
end.