[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