[fpc-pascal] Mozilla XPCOM

José Mejuto joshyfun at gmail.com
Mon Jun 7 15:59:04 CEST 2010


Hello FPC-Pascal,

Monday, June 7, 2010, 10:34:26 AM, you wrote:

JM> safecall is not supported (= ignored) on non-Windows platforms,
JM> because it is completely Windows-specific. Afaik, GCC does not support
JM> any safecall calling convention on Linux either.

It is "silently" changed by stdcall do not ?

>> Linux but mozilla's XPCOM and I think that finally GCC uses a hybird
>> calling convention, it is the same as in Linux but the stack must be
JM> That's actually the standard C calling convention, not a hybrid  
JM> calling convention (= cdecl, as you mention below).

Yes, at the beginning it looks to me strange, because cdecl generates
a totally different code (the TGUID problem) and my first idea was a
non 100% standard calling convention, which is obviously wrong.

>> So the same code to work in
>> Linux (XPCOM) and in Windows:
>>
>> asm
>>    mov eax, [TheCOMInterface];
>>    mov eax,[eax]
>>    push Intf;
>>    push IID;
>>    push ContractID;
>>    push TheCOMInterface;
>>    Call [eax]+16;
>> {$IFDEF LINUX}
>>    add esp,16;
>> {$ENDIF}
>>    call fpc_safecallcheck;
>> end;
JM> Are you certain when using XPCOM with GCC, it automatically transforms
JM> every function so that

First I must conclude that XPCOM in Linux is compiled with GCC and
which version is being used, but I'm quite sure it is GCC ;)

JM> a) the result is passed as a hidden parameter by reference
JM> b) the actual function results becomes an error code

Plain function result is in EAX, if I call (in ASM) QueryInterface
with garbaged IIDs I get "$80004002" in the EAX (NOT_INTERFACE). Just
the same as in Windows using safecall except the stack clean.

JM> c) a check is inserted after every call that checks this error code

To check this I must compile something with GCC and I do not have it
installed and I do not have a source to compile with it. I should
investigate following other paths.

>> Could this be considered a bug in fpc interfaces ?
JM> Yes, it is always wrong to assume that "const" enforces passing by
JM> reference (except when using the mwpascal calling convention).

So a "const x: TGUID" will be passed by reference in safecall and as
16 bytes in cdecl ? Is this OK ? Is this how GCC excepts a const
parameter TGUID to be passed ? I'm asking because now I have changed
my interface definition to use PGUID instead (both windows and linux)
and it works more or less, but now I have a problem in the
TInterfacedObject which seems to be the cause of some crashes, but I
can not say by now if it is related to XPCOM exposing a different
"IUnknown" (maybe cdecl instead stdcall) or TGUID related. I'll
investigate further.

One question, is there any way in fpc to "define" the calling
convention as a C define ? Just something like:

{$IFDEF UNIX}
  {$DEFINE THECALLING cdecl}
{$ELSE}
  {$DEFINE THECALLING safecall}
{$ENDIF}
function x: integer; THECALLING;

I had replaced all safecalls with:

{$IFDEF xx}safecall{$ENDIF}{$IFDEF y}cdecl{$ENDIF}

But it is quite "awful" :)

-- 
Best regards,
 José




More information about the fpc-pascal mailing list