-
-
Notifications
You must be signed in to change notification settings - Fork 608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strive for an ABI-agnostic handling of TypeInfo_Struct.xopEquals and xopCmp #5232
Conversation
To make sure the arguments order (p, q) isn't reversed. This is necessary as the TypeInfo_Struct's function pointers `xopEquals` and `xopCmp` normally point to the struct's `opEquals`/`opCmp` methods, for which lhs `p` must be passed as `this` argument before rhs `q` as single explicit argument. These __ wrappers are only generated if the method doesn't take its single argument by reference.
|
I think this fixes a gdc regression where upstream did a p/q parameter swap (I undid the change). |
|
Can't we generate a non-static member function instead and avoid this mess? |
|
@yebblies: That would be one part of a (cleaner) alternate solution. The second part still involves druntime's Hypothetical D method: |
|
@kinke: ABIs might also pass the |
|
Possibly, we've just had a somewhat related issue in combination with struct-return (hidden |
On 32-bit Windows, MSVC++ passes |
|
@kinke - I gave up on using methods in D codegen a while ago now. All extern(D) functions must abide by the same calling convention because of delegates. |
|
@ibuclaw So do you always pass |
|
@kinke From a top-level view, the It is just of minor annoyance that DMD seems to call |
|
DMD calls the |
|
Maybe the cleanest solution would be to always create the static |
|
I think that we should stop covering for DMD's flaws, and just fix it at the source. :-) |
I.e. by always pointing to the |
|
Out of curiosity.
|
But all of our |
The fact that you tinker with order of arguments for ABI compatibility sake (compatible with what? DMD?) means that LDC is part of the problem that should be fixed. |
Once again I don't quite get what you mean. The problem isn't LDC, the problem is that DMD assumes reversed args in front-end and in druntime/Phobos. If I choose not to reverse the args for Imo, the approach with |
This is a rather myopic statement. There exist large codebases with inline asm for x86/x86_64, and we'd break those in non-obvious ways if we just reversed the argument order compared to what DMD does. Of course you get a free pass on that by just not supporting DMD-style inline ASM at all, but that doesn't mean we (LDC) can just ignore the problem. I think we all agree that the argument order ought to be changed to match C, but this is not the time and place to discuss that. Regarding the issue here, I think we should make sure not to perpetuate any hacks and just fix it in a way that's actually guaranteed to work on all platforms (regardless of whether extern(C) and extern(D) is the same, up to reversing, or completely different). |
|
Rebased in #7561 |
While trying to use a non-reversed parameter order for
extern (D)in LDC on x86_64, I stumbled upon 2 ugly places assuming a reversed parameter order:TypeInfo_Struct.compare()(see Render TypeInfo_Struct.xopCmp ABI-agnostic wrt. parameter order druntime#1417)__xopEquals/__xopCmpfunctionsThe problem is that a pointer to an extern(D) function taking 2 struct references is used to jump either to:
int S.opCmp(ref const S q)with LL signatureint opCmp(S* this = p, S* q), orstatic int S.__xopCmp(ref const S p, ref const S q)with LL signatureint __xopCmp(S* q, S* p)if reversing the args. This function is generated by the front-end in case theopCmpmethod doesn't take its single argument by reference.For this to work,
TypeInfo_Struct.compare()assumed reversed order for extern(D) and called the extern(D) function pointerTypeInfo_Struct.xopCmpwith reversed args(q, p), to get the direct method call right (=> LL order(p, q)).In the DMD front-end, the
static int S.__opCmp(ref const S p, ref const S q)wrapper function needed to take this into account. So it also assumed a reversed arguments order for extern(D) and re-swapped p and q back again (=>return q.opCmp(p)).When not reversing the args for
extern (D)(as it should be on all non-Win32 platforms, according to the docs!), there's no need for any swapping at all.I opted for an
extern (C)approach for function pointer and static function, as that is lowered to a LL signature identical to the method's, as long as thethispointer is passed before the first explicit arg, another (but not new) assumption. I'm not sure whether that's free of any undesired effects though, e.g., for exception handling; name mangling seems to be fine with LDC.At least these 2 places don't have to assume anything about the parameter order of
extern (D)anymore.