Re: [fpc-pascal] Header translation, argument list, array of const?
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/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?
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