Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
object: Wrap fake member function calls into delegates
Browse files Browse the repository at this point in the history
  • Loading branch information
ibuclaw authored and dlang-bot committed Jan 31, 2022
1 parent 12d3078 commit 348a4ff
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions src/object.d
Original file line number Diff line number Diff line change
Expand Up @@ -1884,7 +1884,10 @@ class TypeInfo_Struct : TypeInfo
if (!p1 || !p2)
return false;
else if (xopEquals)
return (*xopEquals)(p1, p2);
{
const dg = _memberFunc(p2, xopEquals);
return dg.xopEquals(p1);
}
else if (p1 == p2)
return true;
else
Expand All @@ -1904,7 +1907,10 @@ class TypeInfo_Struct : TypeInfo
if (!p2)
return true;
else if (xopCmp)
return (*xopCmp)(p2, p1);
{
const dg = _memberFunc(p1, xopCmp);
return dg.xopCmp(p2);
}
else
// BUG: relies on the GC not moving objects
return memcmp(p1, p2, initializer().length);
Expand Down Expand Up @@ -2008,6 +2014,28 @@ class TypeInfo_Struct : TypeInfo
TypeInfo m_arg2;
}
immutable(void)* m_RTInfo; // data for precise GC

// The xopEquals and xopCmp members are function pointers to member
// functions, which is not guaranteed to share the same ABI, as it is not
// known whether the `this` parameter is the first or second argument.
// This wrapper is to convert it to a delegate which will always pass the
// `this` parameter in the correct way.
private struct _memberFunc
{
union
{
struct // delegate
{
const void* ptr;
const void* funcptr;
}
@safe pure nothrow
{
bool delegate(in void*) xopEquals;
int delegate(in void*) xopCmp;
}
}
}
}

@system unittest
Expand Down

0 comments on commit 348a4ff

Please sign in to comment.