On Tuesday, 6 January 2015 at 15:42:22 UTC, Daniel Murphy wrote:
Yes, but __va_argsave is declared in the frontend, which is unnecessary. It was easy enough to make the glue layer reserve the right number of bytes for varargs functions.

I agree. Walter said that he didn't manage to implement it back then, though, and I never looked at the glue layer.

I made it a magic compiler type, and I'll make it automagically pass by ref when used as a function argument on X86_64 posix. That should do it.

Yes, that should indeed do it. I shied away from unilaterially making it a "magic" type in LDC to avoid unpleasant surprises for users. However, it is definitely the cleaner option imho.

How does LDC currently handle it? Does llvm have an easy way to handle the implementation of va_* for you?

LLVM gives us va_start/…, and in theory also va_arg. However, there are two issues why we don't use the latter on Posix x86_64 and rely on Walter's druntime implementation instead:

1) For the template version of va_arg(), we'd need to redo the lowering of D types to the ABI types (passing in registers and so on, which is sadly not automatic in LLVM as its type system can't represent all C types). This could be implemented somewhat easily on top of argTypes, but because of 2) it was not really worth the effort.

2) There is also a va_arg version that takes a TypeInfo at runtime. There doesn't really seem to be a way to implement this on top of what LLVM offers.

And as I said above, we currently have va_list as a pointer type for reasons of simplicity. Thus, we need to actually have our LDC va_start/va_copy intrinsics actually allocate memory for the register save area on the stack before forwarding to the LLVM ones. This is a huge hack, but just about seems to be enough to covervirtually all real-world use cases. In any case, I'm looking forward to cleaning this mess up once your DMD patches are in.

David

Reply via email to