[fpc-devel] Safecall on Linux (and other unices?)

José Mejuto joshyfun at gmail.com
Thu Jul 22 13:52:43 CEST 2010

Hello Joost,

Wednesday, July 21, 2010, 12:46:32 PM, you wrote:

>> I get it to work too, but missing safecall (unix version) makes it
>> unusable as a lot of assembler is needed.
JvdS> That's not true. I managed to get it to work without any assembler.
JvdS> (Only used it to debug and some quick tests)
JvdS> What you have to do is change definitions like:
JvdS> function Bla(test: tsometype) : tresulttype; safecall;
JvdS> to:
JvdS> function Bla(testl: tsometype; _result: tresulttype) : nsresult;
JvdS> extdecl;

Well, changing interface yes, I avoid to change interface, so stack
becomes unbalanced after any function call.

JvdS> And define the extdecl macro to stdcall on Windows and cdecl on Linux.
JvdS> Set the nsresult to the right error code to simulate an exception.

I was trying to not touch interface and as my request about safecall
in unix was "accepted" for a future discussion, I do not investigate
further. Already spend a lot of time trying to figure why "safecall"
works different in unix and in Windows... The silently replace calling
convention confuses me :(

>> It is not 100% cdecl, const records in safecall must be passed as
>> reference while in cdecl a copy of the record is being passed.
JvdS> I don't think so. The gecko-port-definitions are wrong in this regard.
JvdS> They use 'const' but it should be 'var'. That this worked on Windows was
JvdS> just a coincidence. I've replaced these 'const' parameter definitions to
JvdS> 'var' and now they work on Linux and Windows. The headers just weren't
JvdS> translated right in this regard.

Even if declarations in the code are wrong (which I had not checked, I
assumed they were fine) the "const" behavior with record in Windows
safecall and linux cdecl is different. Also parameters not intented to
be modified should not be var but const (IMHO).

JvdS> That was a good starting point, to find out what the problem was
JvdS> precisely. Jonas last comment was where I started. But enabling the
JvdS> exception-handling wasn't enough. Using Safecall on Linut, the caller
JvdS> has to clean up the stack (on windows the callee does). I don't know yet
JvdS> how to the latter. 
JvdS> I don't think the parameter-passing should be changed. Just don't use
JvdS> 'const'. 

I think if it is named safecall is must match windows safecall. Maybe
better use "xpcom" or "unixsafecall" ? Parameter passing mode should
match at all, callee or caller clean up is transparent to the people
working with the library or other library, but how parameters are
passed could bring a lot of confusion.

JvdS> I don't know which version I used. Probably the one from the latest
JvdS> Firefox release. I'll check at home. (tomorrow)

I was using my modified version in the gecko port CCR, which fixes
some bugs, maybe I had introduced new ones ?

Best regards,

More information about the fpc-devel mailing list