Question about functions returning a string

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Question about functions returning a string

Ewald-2
Hi,

Take the following function prototype (in {$mode objfpc}{$H+} for the
record):

    Function SomeFunction(const Data: PChar; const Len: LongWord):
String; cdecl; public;

Looking at the dissasembly of this function, I see that is actually has
three arguments. It looks more like this from an assembler perspective:

    Function SomeFunction(HiddenArgument: Pointer; const Data: PChar;
const Len: LongWord): String; cdecl; public;

Which is, well, quite fascinating really. What is it doing there? I
suspect it has something to do with the result type of the function,
being a string?

Can anybody shed some light on this?

--
Ewald


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Question about functions returning a string

etrusco
On Fri, Nov 28, 2014 at 5:54 PM, Ewald <[hidden email]> wrote:

> Hi,
>
> Take the following function prototype (in {$mode objfpc}{$H+} for the
> record):
>
>     Function SomeFunction(const Data: PChar; const Len: LongWord):
> String; cdecl; public;
>
> Looking at the dissasembly of this function, I see that is actually has
> three arguments. It looks more like this from an assembler perspective:
>
>     Function SomeFunction(HiddenArgument: Pointer; const Data: PChar;
> const Len: LongWord): String; cdecl; public;
>
> Which is, well, quite fascinating really. What is it doing there? I
> suspect it has something to do with the result type of the function,
> being a string?
>
> Can anybody shed some light on this?
>
> --
> Ewald

Are you sure it's not the result that is passed in the first parameter?

http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl

Best regards,
Flávio
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Question about functions returning a string

Ewald-2
On 11/29/2014 12:41 AM, Flávio Etrusco wrote:
> Are you sure it's not the result that is passed in the first parameter?
>
> http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl

Good question, but I don't think so. The first few lines of assembly
from this function seem to read three arguments you see:

  44b360:    53                       push   %rbx
  44b361:    41 54                    push   %r12
  44b363:    41 55                    push   %r13
  44b365:    48 89 fb                 mov    %rdi,%rbx        <-- first
argument, %rdi
  44b368:    41 89 f4                 mov    %esi,%r12d       <-- second
argument, %rsi
  44b36b:    49 89 d5                 mov    %rdx,%r13        <-- third
argument, %rdx

What I forgot to mention was that this is on a x86_64 architecture, so I
based myself on the table found at
http://wiki.osdev.org/Calling_Conventions .

--
Ewald


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Question about functions returning a string

Sven Barth-2
On 29.11.2014 13:56, Ewald wrote:

> On 11/29/2014 12:41 AM, Flávio Etrusco wrote:
>> Are you sure it's not the result that is passed in the first parameter?
>>
>> http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl
>
> Good question, but I don't think so. The first few lines of assembly
> from this function seem to read three arguments you see:
>
>    44b360:    53                       push   %rbx
>    44b361:    41 54                    push   %r12
>    44b363:    41 55                    push   %r13
>    44b365:    48 89 fb                 mov    %rdi,%rbx        <-- first
> argument, %rdi
>    44b368:    41 89 f4                 mov    %esi,%r12d       <-- second
> argument, %rsi
>    44b36b:    49 89 d5                 mov    %rdx,%r13        <-- third
> argument, %rdx
>
> What I forgot to mention was that this is on a x86_64 architecture, so I
> based myself on the table found at
> http://wiki.osdev.org/Calling_Conventions .
>

Just compile with "-al" and you'll see what the compiler uses the
parameters for (the following example is for i386):

=== listing begin ===

.section .text
        .balign 16,0x90
.globl P$TCALLCONV_SOMEFUNCTION$PCHAR$LONGWORD$$ANSISTRING
        .type P$TCALLCONV_SOMEFUNCTION$PCHAR$LONGWORD$$ANSISTRING,@function
P$TCALLCONV_SOMEFUNCTION$PCHAR$LONGWORD$$ANSISTRING:
.Lc1:
# Temps allocated between ebp-524 and ebp-12
# [callconv.pp]
# [6] begin
        pushl %ebp
.Lc3:
.Lc4:
        movl %esp,%ebp
.Lc5:
        subl $524,%esp
# Var aData located at ebp-4
# Var aLen located at ebp-8
# Var $result located at ebp-12
        movl %eax,-4(%ebp)
        movl %edx,-8(%ebp)
        movl %ecx,-12(%ebp)
# [7] Result := Copy(StrPas(aData), 1, aLen);
        leal -268(%ebp),%eax
        pushl %eax
        leal -524(%ebp),%edx
        movl -4(%ebp),%eax
        call SYSTEM_STRPAS$PCHAR$$SHORTSTRING
        leal -524(%ebp),%eax
        movl -8(%ebp),%ecx
        movl $1,%edx
        call fpc_shortstr_copy
        leal -268(%ebp),%eax
        movl -12(%ebp),%edx
        call fpc_shortstr_to_ansistr
# [8] end;
        leave
        ret
.Lc2:
.Le0:
        .size P$TCALLCONV_SOMEFUNCTION$PCHAR$LONGWORD$$ANSISTRING, .Le0 -
P$TCALLCONV_SOMEFUNCTION$PCHAR$LONGWORD$$ANSISTRING

=== listing end ===

In general managed types (which a (Ansi)String is) are passed as parameters.

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Question about functions returning a string

Ewald-2
On 11/29/2014 02:46 PM, Sven Barth wrote:
>
> In general managed types (which a (Ansi)String is) are passed as
> parameters.

That is very interesting knowledge. Thanks!

So in general, one should not use managed types in the prototype of an
exported (public) function? While I do know that the other language
can't do anything useful with it, my thought was that it would be
possible to pass along these managed types (especially string, as it is
a pointer internally) to another pascal function (a callback in my case).

--
Ewald


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Question about functions returning a string

leledumbo
Administrator
> So in general, one should not use managed types in the prototype of an exported (public) function?

Bingo. At least not until we have properly sharable RTL.

> my thought was that it would be
possible to pass along these managed types (especially string, as it is
a pointer internally) to another pascal function (a callback in my case).

You can still pass pointer to its first element as a PChar, treating it read-only in the caller for safety reason (though it's possible to make it writable as well, but the safety burden is propagated to the caller).
Reply | Threaded
Open this post in threaded view
|

Re: Question about functions returning a string

Ewald-2
On 12/01/2014 04:34 AM, leledumbo wrote:
>> So in general, one should not use managed types in the prototype of an
>> exported (public) function?
>
> Bingo. At least not until we have properly sharable RTL.

The problem lies not with a sharable RTL. As mentioned, I do not want to
/use/ these managed types in another language. I just want to pass them
along :-)



>> my thought was that it would be
>> possible to pass along these managed types (especially string, as it is
>> a pointer internally) to another pascal function (a callback in my case).
>
> You can still pass pointer to its first element as a PChar, treating it
> read-only in the caller for safety reason (though it's possible to make it
> writable as well, but the safety burden is propagated to the caller).

Actually I was trying to avoid PChar's ;-)

In the meanwhile, I've fixed my issue by not returning a string as a
result, but as an out parameter:

Function Bla: String;

... becomes ...

Procedure Bla(out Result: String);

This seems to work. How portable it is, I do not know, I guess time will
be the judge and jury on that.

Anyway, thanks to you all!

--
Ewald


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Dan
Reply | Threaded
Open this post in threaded view
|

Re: Question about functions returning a string

Dan
In reply to this post by Ewald-2
On Nov 29, 2014 3:55 AM, "Ewald" <[hidden email]> wrote:
Hi,

Take the following function prototype (in {$mode objfpc}{$H+} for the
record):

    Function SomeFunction(const Data: PChar; const Len: LongWord):
String; cdecl; public;

Looking at the dissasembly of this function, I see that is actually has
three arguments. It looks more like this from an assembler perspective:

    Function SomeFunction(HiddenArgument: Pointer; const Data: PChar;
const Len: LongWord): String; cdecl; public;

Which is, well, quite fascinating really. What is it doing there? I
suspect it has something to do with the result type of the function,
being a string?

Can anybody shed some light on this?

--
Ewald


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal