Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2001-10

solaris

38 messages · 11 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

patrick mergan

Patrick Mergan
email :

Earlier message 20 lines
-----Original Message----- From: Alejandro Néstor Vargas To: Date: Monday, October 01, 2001 11:41 PM Subject: [fpc-devel]solaris I use GNU-pascal on my Ultra 5 (Solaris ) and it works quite well. However, I would alse be very interested if there was a Solaris port... ( especially if I could do some graphics with it ) Patrick >Is there a Solaris port of fpc? > > >_______________________________________________ >fpc-devel maillist - >http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Jonas Maebe
to Pavel V. Ozerski: I compiled today's compiler from source to Win32 target and could not compile with it the…
Pavel V. Ozerski wrote 13 lines
I compiled today's compiler from source to Win32 target and could not compile with it the simplest sample (Internal error 68996): var i:longint; s:shortstring; begin for i:=1 to length(s)do ; end. Please try to fix this bug.

Do a make cycle of the 1.1 compiler with 1.0.5, it will work properly then. The cause is a bug in the set handling of 1.1 (which has been fixed in the mean time)

Jonas

Reply by email

Lee, John

No bug IMHO - works ok with the latest (daily!) win32 snapshot on fpc ftp/www ...why not use that? J

Earlier message 24 lines
-----Original Message----- From: Sent: Wednesday, October 03, 2001 11:00 To: Subject: [fpc-devel]Last 1.1 compiler bug Hello, I compiled today's compiler from source to Win32 target and could not compile with it the simplest sample (Internal error 68996): var i:longint; s:shortstring; begin for i:=1 to length(s)do ; end. Please try to fix this bug. Sincerely, Pavel

Reply by email

Pavel V. Ozerski
to Lee, John

Hello,
I began to write messages.pp for win32 as an analog of messages.pas from Delphi. The first part - describing of WM_... constants is easily solvable: "uses windows" is enough. But Delphi's messages.pas contains also some type definitions which are not translated from MS C header but are introduced by Borland to dispatching Windows messages by TObject.Dispatch. How to translate them not disturbing Borland's (c)? That are very simple records (e.g.,

  TWMActivateApp = record
    Msg: Cardinal;
    Active: BOOL;
    ThreadId: Longint;
    Result: Longint;
  end;

) and I see no alternative ways to define them keeping compatible fields names. I tried to make one large record with many "case integer of WM_..."'s but this way is unusable because some fields with the same names at different offsets must be declared. Declaring all these records as packed seems to be not enough to differ from Borland. Any other ideas? Messages.pp is a very important to port most sources developed for Delphi.

Sincerely, Pavel

Reply by email

Unknown author
to Pavel V. Ozerski
Pavel V. Ozerski wrote 18 lines
Hello, I began to write messages.pp for win32 as an analog of messages.pas from Delphi. The first part - describing of WM_... constants is easily solvable: "uses windows" is enough. But Delphi's messages.pas contains also some type definitions which are not translated from MS C header but are introduced by Borland to dispatching Windows messages by TObject.Dispatch. How to translate them not disturbing Borland's (c)? That are very simple records (e.g., TWMActivateApp = record Msg: Cardinal; Active: BOOL; ThreadId: Longint; Result: Longint; end; ) and I see no alternative ways to define them keeping compatible fields names. I tried to make one large record with many "case integer of WM_..."'s but this way is unusable because some fields with the same names at different offsets must be declared. Declaring all these records as packed seems to be not enough to differ from Borland. Any other ideas? Messages.pp is a very important to port most sources developed for Delphi.

Copying an API is not prohibited; you simply cannot use their sources. I see no problems in what you're trying to do.

Michael.

Reply by email

Pavel V. Ozerski
to Unknown author

Hello,
I wrote a patch to 1.1 (based on 03 oct 2001 sources) to support redefining of default calling conventions. I see some reasons to implement this extension. 1) Some pascal sources contain assembler procedures/functions which code is calling conventions-sensitive. Example: Key Objects Library (KOL) contains many assembler functions which can work correctly only if register calling convention is used (I know that now FPC does not support this calling convention but hope that it will support it in future). In such situations we must rewrite headers of all these procedures, that can be a big and hard work. 2) If in future default calling conventions in FPC will be changed to register, you will must rewrite big parts of RTL. It is evident that this work will require many steps, at initial stages most RTL functions will be remained stdcall. I think, you also would avoid manuall adding to all these functions in RTL source 'stdcall' keyword.

My idea: support new compiler directive: {$Calling <calling_convention>}, e.g. {$calling cdecl} must change default calling conventions of followed functions. Also new command line option, -Cc<calling_convention>, could be implemented. Implementation of these features requered some changes in four units: pdecsub.pas, scandir.pas, globals.pas, options.pas. I could send patched units to FPC team.

Sincerely, Pavel

P.S. Virtual Pascal supports similar feature ({&stdcall on} etc)

Reply by email

Pavel V. Ozerski
to Ingmar Tulva

Hello,
Althoufh my patches are done, I continue to test them.

First problem:
(today's 1.1 version):

If constructors are declared as stdcall, calling this constructor causes run-time error 216 (that is true also for non-patched compiler, but in non-patched compiler this declaration is possible only with "stdcall" keyword. After my patch the compiler automatically sets defauts calling convention to stdcall, therefore I must use my option -Ccpascal or -Ccpopstack to create usable exe-files). Example:

{$ifdef fpc}
{$mode objfpc}
{$endif}
{$apptype console}
program TEST;
type
 tA=class
  constructor create(x1,x2:longint);stdcall;
 end;
constructor tA.create(x1,x2:longint);stdcall;
 begin
 end;
var
 A:tA;
begin
 A:=tA.Create(1,2);
 A.destroy;
end.

Interesting that unpatched compiler generates different asm output depend on existing "stdcall" keyword. Here is entry point and tail of constructor tA.create:
1) if "stdcall" keyword presents:

.globl _$$_TA_$$_CREATE$LONGINT$LONGINT
_$$_TA_$$_CREATE$LONGINT$LONGINT:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
pushl %edi
pushl %esi
pushl %ebx
call FPC_NEW_CLASS
................................................................ testl %esi,%esi
popl %ebx
popl %esi
popl %edi
leave
ret $16

2) after I recompiled my example without "stdcall" keywords:

.globl _$$_TA_$$_CREATE$LONGINT$LONGINT
_$$_TA_$$_CREATE$LONGINT$LONGINT:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
call FPC_NEW_CLASS
................................................................ testl %esi,%esi
leave
ret $16

BTW, I think, second variant is more similar to stdcall... What is its name in FPC now? Then I must make it default instead stdcall.

Second problem:
(today's 1.1 version):
Appliing cdecl calling conventions ("cdecl" keyword) to virtual/override methods causes errors at compiling stage: (e.g. test2.pp(22,2) Error: Asm: Duplicate label _Any) because all methods with the same name get also the same mangled name. Using popstack or cppdecl would be a bad solution because Delphi supports "cdecl" here. But, maybe, there are exists a reason, to automatically interpret cdecl object/class methods as cppdecl (ANSI C does not support classes, therefore this solution seems to be at least logical).

Third problem:

If calling conventions of a method are defined in class description body, Delphi does not require its repeated definition in method header, but FPC finds an error if it is missing. This example could be compiled with Delphi but not with FPC:

{$ifdef fpc}
{$mode objfpc}
{$endif}
{$apptype console}
program TEST;
type
 tA=class
  constructor create(x1,x2:longint);
  procedure X(x1,x2:longint);pascal;
 end;
constructor tA.create(x1,x2:longint);
 begin
 end;
procedure tA.X(x1,x2:longint);
 begin
 end;
var
 A:tA;
begin
 A:=tA.Create(1,2);
 A.destroy;
end.

Sincerely, Pavel

Reply by email

Pavel V. Ozerski
to Pavel V. Ozerski

Hello all,
I tested which code generates Delphi3 for stdcall procedures. It is more similar to code wich is generated with non-patched fpc 1.1 for "default" (declared without any calling-convention-defining keyword) procedures: does not save registers edi, esi, ebx (that's true also for export procedures). Btw, what is the mean to save these registers? I do'nt exclude that it can be useful but then, I think, 'stdcall' supported with current FPC 1.1 is a special variant of stdcall which must have anoter name, e.g., fpccall. Or it is a trick to solve some Win32 callbacks-related problems? Then at least please give a name to 'default anomymous stdcall'!

But please answer to my information: I don't see that you read it. Summary of my previous messages:

1) Is my $calling patch interesting for you?
2) Current 'Stdcall'-declared constructors are buggy (btw, Delphi 3.0 supports only register constructors) and need to be fixed.
3) Inheritance of cdecl methods is also buggy.
4) Evidently declared stdcall procedures/functions are not "pure" stdcalls in reality and differ from "default anonymous stdcalls".

Sincerely, Pavel

Reply by email

Peter Vreman
Hello all, I tested which code generates Delphi3 for stdcall procedures. It is more similar to code

wich is generated with non-patched

fpc 1.1 for "default" (declared without any calling-convention-defining keyword)

procedures: does not save registers edi, esi, ebx

(that's true also for export procedures). Btw, what is the mean to save these registers?

I
do'nt exclude that it can be useful but then,

I think, 'stdcall' supported with current FPC 1.1 is a special variant of stdcall which

must have anoter name, e.g., fpccall. Or it is a

trick to solve some Win32 callbacks-related problems? Then at least please give a name

to
'default anomymous stdcall'!

Delphi always saves ebx,esi,edi and therefor doesn't need to insert extra pushes. FPC uses all available registers and for stdcall it has to insert the pushes to save the original value.

Maybe only changing the order of the pushes and the call to FPC_NEW_CLASS can already solve your problem with constructor and stdcall. But i don't have time to test if it works.

Reply by email

Michael Van Canneyt
to Pavel V. Ozerski: I tested which code generates Delphi3 for stdcall procedures. It is more similar to code…
Pavel V. Ozerski wrote 10 lines
Hello all, I tested which code generates Delphi3 for stdcall procedures. It is more similar to code wich is generated with non-patched fpc 1.1 for "default" (declared without any calling-convention-defining keyword) procedures: does not save registers edi, esi, ebx (that's true also for export procedures). Btw, what is the mean to save these registers? I do'nt exclude that it can be useful but then, I think, 'stdcall' supported with current FPC 1.1 is a special variant of stdcall which must have anoter name, e.g., fpccall. Or it is a trick to solve some Win32 callbacks-related problems? Then at least please give a name to 'default anomymous stdcall'! But please answer to my information: I don't see that you read it. Summary of my previous messages: 1) Is my $calling patch interesting for you?

I'm not yet convinced of it's usefullness. Do not forget that we're trying to be cross-platform, which means that we should keep in mind conventions on other OS-es, such as Unix.

2) Current 'Stdcall'-declared constructors are buggy (btw, Delphi 3.0 supports only register constructors) and need to be fixed.

Constructors are special calls, and should NOT be declared as stdcall. The compiler should give an error on this.

3) Inheritance of cdecl methods is also buggy.

This should be checked.

4) Evidently declared stdcall procedures/functions are not "pure" stdcalls in reality and differ from "default anonymous stdcalls".

I don't know any specification which says what registers should be saved for stdcall. So unless there is an official specification, the fpc way of doing may be just as well as any other...

Michael.

Reply by email

Jonas Maebe
to Michael Van Canneyt
Michael Van Canneyt wrote 9 lines
> But please answer to my information: I don't see that you read it. > Summary of my previous messages: > > 1) Is my $calling patch interesting for you? I'm not yet convinced of it's usefullness. Do not forget that we're trying to be cross-platform, which means that we should keep in mind conventions on other OS-es, such as Unix.

Actually, stdcall is *the* standard calling convention for the 80x86 architecture, no matter under which OS you run. It defines ebx esi and edi as non-volatile (ie if the callee modifies them, it has to save them first) and eax, ecx and edx as non-volatile (if the caller wants to use their current values after it called the subroutine, it should save them first).

Constructors are special calls, and should NOT be declared as stdcall. The compiler should give an error on this.

I agree here, unless it's possible that constructors are exported from libraries, otherwise it will never be possible to use objects/classes defined in FPC programs from Delphi ones.

Jonas

Reply by email

Jonas Maebe
to Jonas Maebe: Actually, stdcall is *the* standard calling convention for the 80x86 architecture, no…
Jonas Maebe wrote 11 lines
> I'm not yet convinced of it's usefullness. Do not forget that we're > trying to be cross-platform, > which means that we should keep in mind conventions on other OS-es, > such as Unix. Actually, stdcall is *the* standard calling convention for the 80x86 architecture, no matter under which OS you run. It defines ebx esi and edi as non-volatile (ie if the callee modifies them, it has to save them first) and eax, ecx and edx as non-volatile (if the caller wants to use their current values after it called the subroutine, it should save them first).

Correction: it's standard as far as the register usage is concerned. I don't know whether there's also a standard order (defined by the ABI) of pushing the parameters (under C, it's in reverse order compared to stdcall IIRC)

Jonas

Reply by email

Marco van de Voort
to Jonas Maebe: Actually, stdcall is *the* standard calling convention for the 80x86 architecture, no…
Show quoted text 19 lines
On donderdag, oktober 11, 2001, at 01:29 , Michael Van Canneyt wrote: >> But please answer to my information: I don't see that you read it. >> Summary of my previous messages: >> >> 1) Is my $calling patch interesting for you? > > I'm not yet convinced of it's usefullness. Do not forget that we're > trying to be cross-platform, > which means that we should keep in mind conventions on other OS-es, > such as Unix. Actually, stdcall is *the* standard calling convention for the 80x86 architecture, no matter under which OS you run. It defines ebx esi and edi as non-volatile (ie if the callee modifies them, it has to save them first) and eax, ecx and edx as non-volatile (if the caller wants to use their current values after it called the subroutine, it should save them first).

I don't exactly know what Pavel's patch does, but I think register parameters should not be like Delphi, but part of a larger scheme to be able to fully control the calling conventions (Pascal/C/register/regsaved) This is also important for being able to inline assembler crossunit to be usefull.

Stdcall should be part of the entire solution, not another hack.

This will also be _very_ important for language interoperability.

Reply by email

Jonas Maebe
to Marco van de Voort
Marco van de Voort wrote 11 lines
> Actually, stdcall is *the* standard calling convention for the 80x86 > architecture, no matter under which OS you run. It defines ebx esi and > edi as non-volatile (ie if the callee modifies them, it has to save > them > first) and eax, ecx and edx as non-volatile (if the caller wants to use > their current values after it called the subroutine, it should save > them > first). I don't exactly know what Pavel's patch does, but I think register parameters should not be like Delphi,

I wasn't talking about register parameters, I was talking about which registers must be saved by the caller and which by the callee. Register parameters are orthogonal to this (ecept that you can only use registers which are caller-saves for register paramters)

Jonas

Reply by email

Pierre Muller
to Pavel V. Ozerski: I'm glad that you find something interesting in my reports. Now I must answer. 1) to…
Show quoted text 16 lines
type t1=class procedure test;cdecl;virtual; end; t2=class(t1) procedure test;cdecl;override; end; procedure t1.test;cdecl; begin end; procedure t2.test;cdecl; begin end; begin end. (test3.pp(10,2) Error: Asm: Duplicate label _test)

This is because cdecl is not only a calling convention, in the sense that it specifies how parameters are sent to the program and how these are disposed, but also a naming convention. A cdecl'ed function
function Cname : longint;
get a '_Cname' assembler label or ('Cname' for ELF unixes).

You can now easily see why the override makes a problem...

Partial solve would be to add the class name, but
anyhow this will have nothing to do with the C++ way of giving internal names to methods.

Thus I would simply suggest to refuse cdecl for method, popstack would still be accepted and has the same effect as cdecl for the calling convention.

I just have one point where I am not sure that popstack and cdecl conventions agree, it is the case of complex (for instance records) return values.

C code for i386 uses ret $4 in such cases,
but popstack might not do so...

Reply by email

Peter Vreman
>Delphi always saves ebx,esi,edi and therefor doesn't need to insert extra pushes. FPC

uses

>all available registers and for stdcall it has to insert the pushes to save the

original

Show quoted text 18 lines
>value. I wrote a small test unit: unit dtest2; interface procedure TestProc(x1,x2:longint);stdcall; implementation procedure TestProc(x1,x2:longint);stdcall; begin asm nop end; end; begin end. Firstly I compiled it with Delphi 3.0 (dcc -J -$O- dtest), then disassembled OBJ-file

with
Watcom disassembler

Show quoted text 9 lines
(wdisasm -au -p dtest.OBJ). Here is procedure TestProc assembler code: TestProc: pushl %ebp movl %esp,%ebp nop popl %ebp ret $0x0008 I see no saving ebx,esi,edi here. Btw, this obj file could be linked not only to Delphi

or
CPPBuilder projects.

The same code I get if I cut out 'stdcall' keywords form dtest2 source and compile it

with
FPC 1.1:

Show quoted text 8 lines
_DTEST2$$_TESTPROC$LONGINT$LONGINT: pushl %ebp movl %esp,%ebp nop leave ret $8 But if I restore 'stdcall' keywords and compile unit with FPC 1.1, saving registers

will
be added:

Show quoted text 14 lines
_DTEST2$$_TESTPROC$LONGINT$LONGINT: pushl %ebp movl %esp,%ebp pushl %edi pushl %esi pushl %ebx nop popl %ebx popl %esi popl %edi leave ret $8 My yesterday's tests demonstrated that also for export procedures Delphi 3.0 does not

include saving registers into code.

The assembler parsers doesn't keep track of used registers and simply says that it uses all registers.

Additionally, these tests demonstrate that default conventions which uses FPC are not

the
same as wich uses FPC for

procedures wich have 'stdcall' keyword.

The default calling convention of FPC is that it thinks that all registers can be changed. We never said that FPC uses stdcall or is Delphi compatible with it's default calling convention.

Reply by email

Peter Vreman
Thus I would simply suggest to refuse cdecl for method, popstack would still be accepted and has the same effect as cdecl for the calling convention.

Kylix also doesn't allow cdecl after methods.

Reply by email

Pavel V. Ozerski
to Peter Vreman: wich is generated with non-patched procedures: does not save registers edi, esi, ebx I…

Hello,
I'm glad that you find something interesting in my reports. Now I must answer.

1) to Peter:

Delphi always saves ebx,esi,edi and therefor doesn't need to insert extra pushes. FPC uses all available registers and for stdcall it has to insert the pushes to save the original value.

I wrote a small test unit:

unit dtest2;
interface
procedure TestProc(x1,x2:longint);stdcall;
implementation
procedure TestProc(x1,x2:longint);stdcall;
 begin
  asm
   nop
  end;
 end;
begin
end.

Firstly I compiled it with Delphi 3.0 (dcc -J -$O- dtest), then disassembled OBJ-file with Watcom disassembler (wdisasm -au -p dtest.OBJ). Here is procedure TestProc assembler code:

TestProc: pushl %ebp
movl %esp,%ebp
nop
popl %ebp
ret $0x0008

I see no saving ebx,esi,edi here. Btw, this obj file could be linked not only to Delphi or CPPBuilder projects.

The same code I get if I cut out 'stdcall' keywords form dtest2 source and compile it with FPC 1.1: _DTEST2$$_TESTPROC$LONGINT$LONGINT:
pushl %ebp
movl %esp,%ebp
nop
leave
ret $8

But if I restore 'stdcall' keywords and compile unit with FPC 1.1, saving registers will be added: _DTEST2$$_TESTPROC$LONGINT$LONGINT:
pushl %ebp
movl %esp,%ebp
pushl %edi
pushl %esi
pushl %ebx
nop
popl %ebx
popl %esi
popl %edi
leave
ret $8

My yesterday's tests demonstrated that also for export procedures Delphi 3.0 does not include saving registers into code. Additionally, these tests demonstrate that default conventions which uses FPC are not the same as wich uses FPC for procedures wich have 'stdcall' keyword.

2) To Michael:

> 1) Is my $calling patch interesting for you? I'm not yet convinced of it's usefullness. Do not forget that we're trying to be cross-platform, which means that we should keep in mind conventions on other OS-es, such as Unix.

Nothing prohibits to support very different calling conventions in this compiler directive. It is more universal than syntax used in Virtual Pascal ({$stdcall ... etc ). That is easy to make support in this $calling directive all calling conventions supported in FPC, including future extensions. On the other hand, this directive could help to solve some programming problems (e.g, porting code written for Delphi). Upon my honour, I did not forget not only about Unix but even about PalmOS!

Constructors are special calls, and should NOT be declared as stdcall. The compiler should give an error on this.

But first, compiler does not find error here, second, PASCAL- and POPSTACK- declared constructors seem to be not buggy (therefore I see no reason to prohibit them), third, that is easy to make ignoring $calling directive for constructors (I know the way already now).

> 3) Inheritance of cdecl methods is also buggy. This should be checked.

This is checked yesterday!

type
t1=class
 procedure test;cdecl;virtual;
end;
t2=class(t1)
 procedure test;cdecl;override;
end;
procedure t1.test;cdecl;
 begin
 end;
procedure t2.test;cdecl;
 begin
 end;
begin
end.
(test3.pp(10,2) Error: Asm: Duplicate label _test)
I don't know any specification which says what registers should be saved for stdcall. So unless there is an official specification, the fpc way of doing may be just as well as any other...

I think, current "Evident stdcall" in fpc should be renamed.

To Jonas:

Show quoted text 6 lines
Actually, stdcall is *the* standard calling convention for the 80x86 architecture, no matter under which OS you run. It defines ebx esi and edi as non-volatile (ie if the callee modifies them, it has to save them first) and eax, ecx and edx as non-volatile (if the caller wants to use their current values after it called the subroutine, it should save them first).

Then why Delphi does not save registers in stdcall procedures? I'm sure, it is not optimization issue : I added built-in-assember instruction mov edi,eax into body of stdcall procedure but Delphi 3 also did not save edi! Also if stdcall must save these registers then default calling conventions in fpc are not true stdcall and they should have a name.

I agree here, unless it's possible that constructors are exported from libraries, otherwise it will never be possible to use objects/classes defined in FPC programs from Delphi ones.

Redeclaring of constructors calling conventions should be useful for CPPclasses, I think. I hope also that CPPclasses will be usable not only with gcc but also at least with open Watcom and free Borland C++.

Sincerely, Pavel

Reply by email

Peter Vreman
Show quoted text 5 lines
Hello, Pierre, > Thus I would simply suggest to refuse cdecl for method, >popstack would still be accepted and has the same effect as >cdecl for the calling convention. I think, automatical replacing cdecl to cppdecl for methods would be a best solution

Implicit changing of meaning should always be avoided if possible. Since cppdecl is not working the exact meaning can differ from cdecl. And the solution in your example is simple, just use cppdecl for methods instead of cdecl

Reply by email

Peter Vreman
Peter, you wrote now: >The default calling convention of FPC is that it thinks that all registers can be

changed.

>We never said that FPC uses stdcall or is Delphi compatible with it's default calling >convention. But acually they seem to be the same as "delphi stdcall" and not the same as "fpc

stdcall"

I don't understand this? There is no "delphi stdcall" or "fpc stdcall". The functionality of stdcall is the same. Only the codegeneration differs

Reply by email

Pavel V. Ozerski
to Peter Vreman: Implicit changing of meaning should always be avoided if possible. Since cppdecl is not…

Peter,

Implicit changing of meaning should always be avoided if possible. Since cppdecl is not working the exact meaning can differ from cdecl. And the solution in your example is simple, just use cppdecl for methods instead of cdecl

Peter, I understand, how to avoid problems in my own programs. But I mean now about other (also beginning) programmers. I'm able to understand causes of compiler behavior in this case but I'm not sure that every programmer can quickly find solution here. Therefore the compiler itself must help (at least generate more informative error message).

Pavel

Reply by email

Pavel V. Ozerski
to Peter Vreman: changed. stdcall" I don't understand this? There is no "delphi stdcall" or "fpc stdcall".…
I don't understand this? There is no "delphi stdcall" or "fpc stdcall". The functionality of stdcall is the same. Only the codegeneration differs

The functionality is also not always the same: if inside "fpc stdcall" procedure something will change these three registers, it will not always cause appliction crash because they will be retored before return. Procedures/functions having default calling conventions and compiled with FPC or procedures/functions declared as stdcall but compiled with Delphi are potentially more dangerous. "FPC stdcall" is something middle between "Delphi stdcall" and safecall. I'm concordant with you, the functionality under normal conditions is the same. But the situation with stdcall constructors demonstrates that the difference can be important somewhere.

Pavel

Reply by email

Pavel V. Ozerski
to Peter Vreman: Neither does FPC.
> >Kylix also doesn't allow cdecl after methods. > But does Kylix support C++ classes? Neither does FPC.

Peter, there are exists CPPCLASS keyword in FPC, initial work to support C++ classes is started long time ago. Unfortunatelly, now it is impossible, to use C++ class libraries with FPC, but I hope that CPPClasses will be not exluded from FPC.

Pavel

Reply by email

Jonas Maebe
to Pavel V. Ozerski: The functionality is also not always the same: if inside "fpc stdcall" procedure…
Pavel V. Ozerski wrote 12 lines
The functionality is also not always the same: if inside "fpc stdcall" procedure something will change these three registers, it will not always cause appliction crash because they will be retored before return. Procedures/functions having default calling conventions and compiled with FPC or procedures/functions declared as stdcall but compiled with Delphi are potentially more dangerous. "FPC stdcall" is something middle between "Delphi stdcall" and safecall. I'm concordant with you, the functionality under normal conditions is the same. But the situation with stdcall constructors demonstrates that the difference can be important somewhere.

That procedures/functions with the default calling convention are incompatible between Delphi and FPC, is true. Not only due to the differences in register saving, but also due to differences in parameter passing (Delphi supports register parameters, FPC doesn't (yet)). I think that's exactly the reason why you can specify calling conventions.

However, when declaring them as stdcall, they should be compatible. Delphi should save ebx/esi/edi if they're modified (and I think assembler statements don't count, just like FPC's assembler parser, Delphi's parser probably also doesn't try to "understand" the assembler code).

The fact that there are problems with stdcall constructors under FPC, is just that the popped esi at the end overwrites the pointer to the generated object (which is normally returned in esi) I think. So we should indeed reject cdecl/stdcall/... for constructors.

Jonas

Reply by email

Jonas Maebe
to Pavel V. Ozerski: I'm glad that you find something interesting in my reports. Now I must answer. 1) to…
Pavel V. Ozerski wrote 8 lines
TestProc: pushl %ebp movl %esp,%ebp nop popl %ebp ret $0x0008 I see no saving ebx,esi,edi here. Btw, this obj file could be linked not only to Delphi or CPPBuilder projects.

That's because you didn't modify any either. Delphi expects you to save the necessary registers yourself when you use assembler.

Show quoted text 14 lines
But if I restore 'stdcall' keywords and compile unit with FPC 1.1, saving registers will be added: _DTEST2$$_TESTPROC$LONGINT$LONGINT: pushl %ebp movl %esp,%ebp pushl %edi pushl %esi pushl %ebx nop popl %ebx popl %esi popl %edi leave ret $8

FPC OTOH, expects that all registers are modified in an assembler statement, unless you specify the list of modified registers using the ['reg1','reg2'] notation at the end of the assembler procedure.

Show quoted text 5 lines
My yesterday's tests demonstrated that also for export procedures Delphi 3.0 does not include saving registers into code. Additionally, these tests demonstrate that default conventions which uses FPC are not the same as wich uses FPC for procedures wich have 'stdcall' keyword.

This has nothing to do with differences in calling conventions, but with differences in assuming which registers are destroyed in an assembler block. Just include some real code which uses a lot of registers in your test procedure, and Delphi should save those registers too.

> Actually, stdcall is *the* standard calling convention for the 80x86

[cut]

Then why Delphi does not save registers in stdcall procedures?

See above, it assumes that you do that yourself when using assembler blocks.

I'm sure, it is not optimization issue : I added built-in-assember instruction mov edi,eax into body of stdcall procedure but Delphi 3 also did not save edi!

Same reason as above.

Also if stdcall must save these registers then default calling conventions in fpc are not true stdcall and they should have a name.

Default FPC calling conventions = "fpc calling conventions". They don't need a name currently, because we don't have a global switch to change the default calling convention. Is there a directive to select "default Delphi calling conventions" in Delphi?

Jonas

Reply by email

Michael Van Canneyt
to Jonas Maebe
Jonas Maebe wrote 66 lines
On vrijdag, oktober 12, 2001, at 10:30 , Pavel V. Ozerski wrote: > TestProc: pushl %ebp > movl %esp,%ebp > nop > popl %ebp > ret $0x0008 > > I see no saving ebx,esi,edi here. Btw, this obj file could be linked > not only to Delphi or CPPBuilder projects. That's because you didn't modify any either. Delphi expects you to save the necessary registers yourself when you use assembler. > But if I restore 'stdcall' keywords and compile unit with FPC 1.1, > saving registers will be added: > _DTEST2$$_TESTPROC$LONGINT$LONGINT: > pushl %ebp > movl %esp,%ebp > pushl %edi > pushl %esi > pushl %ebx > nop > popl %ebx > popl %esi > popl %edi > leave > ret $8 FPC OTOH, expects that all registers are modified in an assembler statement, unless you specify the list of modified registers using the ['reg1','reg2'] notation at the end of the assembler procedure. > My yesterday's tests demonstrated that also for export procedures > Delphi 3.0 does not include saving registers into code. > Additionally, these tests demonstrate that default conventions which > uses FPC are not the same as wich uses FPC for > procedures wich have 'stdcall' keyword. This has nothing to do with differences in calling conventions, but with differences in assuming which registers are destroyed in an assembler block. Just include some real code which uses a lot of registers in your test procedure, and Delphi should save those registers too. >> Actually, stdcall is *the* standard calling convention for the 80x86 [cut] > Then why Delphi does not save registers in stdcall procedures? See above, it assumes that you do that yourself when using assembler blocks. > I'm sure, it is not optimization issue : I added built-in-assember > instruction mov edi,eax into body > of stdcall procedure but Delphi 3 also did not save edi! Same reason as above. > Also if stdcall must save these registers then default calling > conventions in fpc are not true stdcall > and they should have a name. Default FPC calling conventions = "fpc calling conventions". They don't need a name currently, because we don't have a global switch to change the default calling convention. Is there a directive to select "default Delphi calling conventions" in Delphi?

No. Delphi uses register calling convention, unless specifically instructed otherwise in the declaration.

Michael.

Reply by email

Unknown author
to Michael Van Canneyt: I'm not yet convinced of it's usefullness. Do not forget that we're trying to be…

Date sent: Thu, 11 Oct 2001 13:29:43 +0200 (W. Europe Daylight Time) From: Michael Van Canneyt
To:
Subject: Re: [fpc-devel]I suggest a new FPC feature Send reply to:

Show quoted text 5 lines
> 1) Is my $calling patch interesting for you? I'm not yet convinced of it's usefullness. Do not forget that we're trying to be cross-platform, which means that we should keep in mind conventions on other OS-es, such as Unix.

I'm not sure this is a good reason to avoid the patch. In contrary, I even think it's one more reason for it. The more platforms supported, the higher can grow the amount of needed calling conventions (for example, we'd need support for "far 16 pascal" calling convention for some OS/2 libraries :-( ). If you create an interface unit for some 3rd party (or system) library, you could add one global parameter at the top and stop being afraid of forgetting one "cdecl" in the list of 367 ( ;-) ) function declarations.

Tomas

Reply by email

Unknown author
to Pierre Muller: This is because cdecl is not only a calling convention, in the sense that it specifies…

Date sent: Fri, 12 Oct 2001 10:02:44 +0200
To:
From: Pierre Muller
Subject: Re: [fpc-devel]I suggest a new FPC feature Send reply to:

This is because cdecl is not only a calling convention, in the sense that it specifies how parameters are sent to the program and how these are disposed, but also a naming convention.

BTW, this is something I don't like very much - these are two distinct things and it should be possible to specify them separately, IMHO (although "cdecl" still might and probably should keep its current behaviour, of course). But the same naming convention (keeping the original name, i.e. without unit name etc.) is applicable (and needed) for other calling conventions as well, not only the C one.

Tomas

Reply by email

Peter Vreman
Show quoted text 14 lines
> > 1) Is my $calling patch interesting for you? > > I'm not yet convinced of it's usefullness. Do not forget that we're > trying to be cross-platform, which means that we should keep in mind > conventions on other OS-es, such as Unix. I'm not sure this is a good reason to avoid the patch. In contrary, I even think it's one more reason for it. The more platforms supported, the higher can grow the amount of needed calling conventions (for example, we'd need support for "far 16 pascal" calling convention for some OS/2 libraries :-( ). If you create an interface unit for some 3rd party (or system) library, you could add one global parameter at the top and stop being afraid of forgetting one "cdecl" in the list of 367 ( ;-) ) function declarations.

I also think that a $calling directive can be added. It can also be used for C import files or win32 DLL export

Reply by email