Am 07.12.2019 um 22:46 schrieb bla...@blaise.ru:
On 07.12.2019 21:39, Sven Barth wrote:
I'm arguing that there is no builtin way to *access* the parameters passed in such a way.

You are arguing that /now/, but it is not what you said earlier. You said, verbatim:
one can not access VarArgs parameters inside a Delphi function (without resorting to assembly)
Like I said, this is factually incorrect.

I had forgotten about pointers to the stack area which I got reminded off when I found the link I sent. But that doesn't change that there is no official way to access such parameters.


there are hacks

A custom va_list implementation, fully conforming to the ABI and particularities of the compiler, is not necessarily a hack. (In the sense that is not of questionable design, implementation quality, and maintainability.)

but this is not guaranteed to work on every platform.

Where did that requirement of "every platform" suddenly come from? One needs to roll out their own va_list implementations only for the platforms A) that he targets, and B) on which the stock implementation is not provided.

It's to show the restriction of the approach that is shown in the link. While it works on i386-win32 and probably also x86_64-win64 it would fail on e.g. x86_64-linux (or any other x86_64 platform following the Sys V ABI). I give you point A, but B is moot as there is no stock implementation in Delphi for *any* platform.


an anonymous function with varargs modifier will not be allowed anyway

Right. FTR, my patch will eventually allow exactly that, and so does DCC already. Or are you still not aware of the latter? For the fourth time: VARARGS is allowed and works with DCC, on both sides, without BASM or ugly hacks, on more than one platform :) Some of them even have stock implementations of va_list, FPC should take a hint.

But only on i386-win32 and x86_64-win64. On Sys V ABI x86_64 targets there is no way around it, because the arguments are passed in registers, not in the stack area. That's why GCC implements the va[ist functionality using compiler intrinsics instead of macros as is the case on Windows.

And no, your patch WILL NOT allow that. We've consciously decided AGAINST implementing varargs functions in Pascal (see https://wiki.freepascal.org/User_Changes_2.6.0#Array_of_const_parameters_and_cdecl_routines ) and we DO NOT WANT to support this.

So what will be allowed is this:

=== code begin ===

type
  TSomeProc = reference to procedure(aFmt: PChar); cdecl; varargs;

=== code end ===

but not this:

=== code begin ===

var
  proc: TSomeProc;
begin
  proc := procedure(aFmt: PChar) cdecl varargs
    begin
      { do something with aFmt and the variadic arguments }
    end;
end.

=== code end ===

Just as it is for procedure and method variables.

And yes, it makes sense to allow it for one, but to deny it for another, because as TSomeProc is an interface it can be used to interface (no pun intended) with external code that provides such an interface as well (e.g. delegates in COM/WinRT, though I have yet so see a varargs function there...).

For Pascal code there is "array of const" which is better anyway, cause all values contain type information about the passed value. And it works cross platform (which for FPC *is* important).


You need procvar specific functionality, because you need to restrict the available modifiers to those available for procvars.

And if I use the procvardef parser, I, like Jonas, would need to prohibit "OF OBJECT" and "IS NESTED". One extra work for another.

The code of procvar_dec as it is currently does not forbid it. So that will need to be improved anyway.


You extend tprocvardef.create with a doregister parameter
you convert the procvar to an interface method and then free the no longer required procvardef.

Right. The unnecessary work I am currently avoiding.
Since I have not yet submitted that part for review, let us avoid premature pointless discussion.

you're parsing something that's in essence a fancy procedure/method variable which is completely independant of it being implemented by an interface

"Completely independent"?
You do realise that method reference types "being <...> interface[s]" is pretty much a part of the specification?
----------8<----------
type M = reference to procedure (const N: Integer);
type C = class (TInterfacedObject, M)
    procedure Invoke(const N: Integer); virtual; abstract;
end;
end.
----------8<----------

Yes, it's part of the specification (and I'm not arguing that!), but for the parser itself it is simply an implementation detail. Just like method pointers are implemented using a record that contains both a CodePointer and a data Pointer.

Regards,
Sven
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to