Subject: D2 register calling convention bug
I have found a problem with D2's register (default) calling convention that
looks suspiciously like a bug to me (code attached below; do a File|New app;
drop a label on the form; trade the default unit1.pas with the one presented
here).
I have a little function ("Get_Number" below) that gets a string in as a VAR
parameter, reads out 5 chars from the start of the string, convert these to a
number, and chop off the 5 chars from the string. Another routine that takes
two (or more in this example) numbers as parameters ("Test" below) gets called
with the output from "Get_Number" as parameters.
The funny thing is, when using register cc and two or three parameters, the
parameters get reversed in their order on the stack (when expected output would
be "1 2 3" it comes out as "3 2 1").
If more than three parameters are used, the last two will come first, and in
reverse order, then the rest comes in the correct order (when expected output
would be "1 2 3 4 5" it comes out as " 5 4 1 2 3").
If I uncomment the pascal cc identifier, it works as expected. I couldn't find
anything in the docs that said VAR strings were to be avoided with register cc,
so I assume it's some D2 problem. BTW, the code as presented uses 'old' short
strings but I get the same result if I define string255 = AnsiString.
---example---
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
string255 = string[255];
TForm1 = class(TForm)
Label1: TLabel;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
prn_str : string255;
procedure Test(Int1, Int2, Int3, Int4, Int5 : integer); { pascal; }
end;
Const
NUMSTR_LENGTH = 5;
var
Form1: TForm1;
implementation
{$R *.DFM}
function Get_Number(var prn_str : string255) : longint;
var
s : string[NUMSTR_LENGTH];
len : integer;
begin
len := length( prn_str );
if len >= NUMSTR_LENGTH then
begin
s := Copy(prn_str,1,NUMSTR_LENGTH);
prn_str := Copy(prn_str,NUMSTR_LENGTH+1,len-NUMSTR_LENGTH);
result := StrToint(s);
end else
result := 0;
end;
procedure TForm1.Test(Int1, Int2, Int3, Int4, Int5 : integer);
begin
Label1.Caption := (IntToStr(Int1)+' '+IntToStr(Int2)+' '+IntToStr(Int3)+'
'+IntToStr(Int4)+' '+IntToStr(Int5));
end;
procedure TForm1.FormShow(Sender: TObject);
begin
prn_str := ' 1 2 3 4 5';
Test(Get_Number(prn_str), Get_Number(prn_str), Get_Number(prn_str),
Get_Number(prn_str), Get_Number(prn_str));
end;
end.
--
Mr.Hillbilly (eiv...@infolink.no) http://www.sn.no/~eivind
tHyperSoft HyperReader 1.0t