Re: [fpc-pascal] Header translation, argument list, array of const?

2012-06-30 Thread Sven Barth
Am 30.06.2012 03:25 schrieb "kyan" :
> A pascal open array of const which is the closest concept to a C
> ellipsis may have similar semantics but its binary representation on
> the parameter stack is completely different. First of all, since it
> has to work in all calling conventions and not just cdecl the high
> bound of passed array elements is pushed in the stack after a pointer
> to an array of TVarRec structures that each contains a type attribute
> and either a value or a pointer to the value of the parameter. So the
> open array doesn't need to be the last parameter like the C ellipsis
> and there can be more than one in a routine signature. So your
> declaration of purple_prpl_got_user_status
>
> procedure purple_prpl_got_user_status(account: PPurpleAccount;
>   name_, status_id: PChar;
>   par3: array of const);
>
> is equivalent to:
>
> procedure purple_prpl_got_user_status(account: PPurpleAccount;
>   name_, status_id: PChar;
>   par3: PVarRecArray; par3HighBound: Integer);
>
> So the caller pushes only a pointer to a TVarRec array and an integer
> while the function expects a continuous "stream" of parameters. If you
> pass [] the compiler generates code to push a nil pointer (zero
> PtrInt) and a high bound of -1. If the C function can handle these
> values on the stack it *sort of* works by accident, but it will
> probably fail if it tries to read past the -1 high bound for a
> specific value of status_id that requires more variable parameters.

Your explanation is very nice and mostly correct, but in case of external
cdecl functions in FPC the "varargs" modifier and a "array of const"
parameter imply the same C compatible parameter passing in the compiler.
See also here:
http://freepascal.org/docs-html/ref/refsu77.html#x180-1914.9.17

The only difference is when calling the functions. E.g.:

procedure a(args: array of const); cdecl; external;
procedure b; cdecl; varargs; external;

begin
  a([1, 'foo', somevar]);
  b(1, 'foo', somevar);
end.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Header translation, argument list, array of const?

2012-06-30 Thread Bernd
2012/6/30 Sven Barth :

> Your explanation is very nice and mostly correct, but in case of external
> cdecl functions in FPC the "varargs" modifier and a "array of const"
> parameter imply the same C compatible parameter passing in the compiler. See
> also here:
> http://freepascal.org/docs-html/ref/refsu77.html#x180-1914.9.17
>
> The only difference is when calling the functions. E.g.:
>
> procedure a(args: array of const); cdecl; external;
> procedure b; cdecl; varargs; external;
>
> begin
>   a([1, 'foo', somevar]);
>   b(1, 'foo', somevar);
> end.

This means in my case I declared the external function correctly and
only need to pass
[nil]
to make it a null terminated list? Because I tried this last night and
looked at the generated assembler and if I for example call it with

  purple_prpl_got_user_status(@self, Pointer(AName),
Pointer(AStatusID), [1,2,3,nil]);

then it will generate the following code:

0162EF17 6a00 push   $0x0
0162EF19 6a03 push   $0x3
0162EF1B 6a02 push   $0x2
0162EF1D 6a01 push   $0x1
0162EF1F ff75f8   pushl  -0x8(%ebp)
0162EF22 ff75fc   pushl  -0x4(%ebp)
0162EF25 8b45f4   mov-0xc(%ebp),%eax
0162EF28 50   push   %eax
0162EF29 e8b20afaff   call   0x15cf9e0


so its just just pushing the contents of the list onto the stack as
they are and If I pass [] there would be nothing pushed at all, so the
right thing for me to do in this case would be to call it with

  purple_prpl_got_user_status(@self, Pointer(AName), Pointer(AStatusID), [nil]);

0162EF17 6a00 push   $0x0
0162EF19 ff75f8   pushl  -0x8(%ebp)
0162EF1C ff75fc   pushl  -0x4(%ebp)
0162EF1F 8b45f4   mov-0xc(%ebp),%eax
0162EF22 50   push   %eax
0162EF23 e8b80afaff   call   0x15cf9e0


so that it will push exactly one zero onto the stack, so it gets what
it wants (an empty null-terminated list)? Then my only mistake was to
assume that [] would automatically generate a null terminated list
(for automagic[TM]  C-friendlyness) just like strings do?
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Header translation, argument list, array of const?

2012-06-30 Thread Sven Barth
Am 30.06.2012 12:50 schrieb "Bernd" :
>
> 2012/6/30 Sven Barth :
>
> > Your explanation is very nice and mostly correct, but in case of
external
> > cdecl functions in FPC the "varargs" modifier and a "array of const"
> > parameter imply the same C compatible parameter passing in the
compiler. See
> > also here:
> > http://freepascal.org/docs-html/ref/refsu77.html#x180-1914.9.17
> >
> > The only difference is when calling the functions. E.g.:
> >
> > procedure a(args: array of const); cdecl; external;
> > procedure b; cdecl; varargs; external;
> >
> > begin
> >   a([1, 'foo', somevar]);
> >   b(1, 'foo', somevar);
> > end.
>
> This means in my case I declared the external function correctly and
> only need to pass
> [nil]
> to make it a null terminated list? Because I tried this last night and
> looked at the generated assembler and if I for example call it with
>
>   purple_prpl_got_user_status(@self, Pointer(AName),
> Pointer(AStatusID), [1,2,3,nil]);
>
> then it will generate the following code:
>
> 0162EF17 6a00 push   $0x0
> 0162EF19 6a03 push   $0x3
> 0162EF1B 6a02 push   $0x2
> 0162EF1D 6a01 push   $0x1
> 0162EF1F ff75f8   pushl  -0x8(%ebp)
> 0162EF22 ff75fc   pushl  -0x4(%ebp)
> 0162EF25 8b45f4   mov-0xc(%ebp),%eax
> 0162EF28 50   push   %eax
> 0162EF29 e8b20afaff   call   0x15cf9e0
> 
>
> so its just just pushing the contents of the list onto the stack as
> they are and If I pass [] there would be nothing pushed at all, so the
> right thing for me to do in this case would be to call it with
>
>   purple_prpl_got_user_status(@self, Pointer(AName), Pointer(AStatusID),
[nil]);
>
> 0162EF17 6a00 push   $0x0
> 0162EF19 ff75f8   pushl  -0x8(%ebp)
> 0162EF1C ff75fc   pushl  -0x4(%ebp)
> 0162EF1F 8b45f4   mov-0xc(%ebp),%eax
> 0162EF22 50   push   %eax
> 0162EF23 e8b80afaff   call   0x15cf9e0
> 
>
> so that it will push exactly one zero onto the stack, so it gets what
> it wants (an empty null-terminated list)? Then my only mistake was to
> assume that [] would automatically generate a null terminated list
> (for automagic[TM]  C-friendlyness) just like strings do?

I have now looked at your mail again. Normally you don't need to explicitly
pass a "Nil" (whatever of the earlier mentioned variants you chose) as e.g.
for printf the following works:

printf("%d %d %d", 1, 2, 3);

or

printf("%d %d %d", [1, 2, 3]);

(depending on the declaration)

But the comment above the original C function you mentioned in your initial
mail explicitly states that you must pass a Null-terminated list, which the
compiler doesn't do by itself. Maybe that is told to GCC by the
G_GNUC_NULL_TERMINATED define (whatever it resolves to...)

Nevertheless passing a Nil at the end should be the correct approach in
your specific case.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal