Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions runtime/druntime/src/core/stdc/stdarg.d
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,24 @@ else version (DigitalMars)
*/
version (GNU)
T va_arg(T)(ref va_list ap); // intrinsic
else version (WebAssembly){
pragma(LDC_va_arg)
T ldc_va_arg(T)(ref va_list ap);
T va_arg(T)(ref va_list ap)
{
static if (__traits(isScalar, T) || is(T == U*, U))
{
return ldc_va_arg!T(ap);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use this LLVM intrinsic anywhere else, it's basically useless and only works for trivial types (if at all), where the implementation is trivial anyway (your else branch most likely).

After glancing at https://github.com/ldc-developers/ldc/blob/master/gen/abi/wasm.cpp and the last paragraph in https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md#function-arguments-and-return-values, I think the else branch might really suffice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if the else branch suffices, I'd say incorporate it in the generic va_arg template below, as for the other archs.

}
else
{
ap = ap.alignUp!(T.alignof);
auto p = cast(T*) ap;
ap += T.sizeof.alignUp;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the size needs to be aligned up here; this will be taken care of by the alignUp!(T.alignof) for the next argument. If I understand the spec paragraph correctly:

Arguments are arranged in order in the buffer, with each argument placed at the lowest appropriately aligned address after the previous argument.

return *p;
}
}
}
else
T va_arg(T)(ref va_list ap)
{
Expand Down
Loading