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