From c77dd21cd88fa38ec055e7b428c0419515e32394 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 15 Mar 2015 23:12:15 +0100 Subject: [PATCH 1/2] Render TypeInfo_Struct.compare() ABI-agnostic wrt. parameter order --- src/object.d | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/object.d b/src/object.d index 0be888d296..c9a0b301a2 100644 --- a/src/object.d +++ b/src/object.d @@ -1057,7 +1057,7 @@ class TypeInfo_Struct : TypeInfo if (!p2) return true; else if (xopCmp) - return (*xopCmp)(p2, p1); + return (*xopCmp)(p1, p2); else // BUG: relies on the GC not moving objects return memcmp(p1, p2, init().length); @@ -1101,10 +1101,21 @@ class TypeInfo_Struct : TypeInfo @safe pure nothrow { - size_t function(in void*) xtoHash; - bool function(in void*, in void*) xopEquals; - int function(in void*, in void*) xopCmp; - string function(in void*) xtoString; + size_t function(in void*) xtoHash; + /* The xopEquals and xopCmp function pointers usually point to the struct's + * opEquals and opCmp methods. If the method doesn't take its single + * argument by reference, the front-end injects a static __xopEquals/ + * __xopCmp function (taking 2 arguments, lhs `p` and rhs `q`). + * + * In the method case, lhs `p` is the `this` argument and must be passed + * as first argument before rhs `q`. + * Enforce this arguments order by marking the pointed-to functions as + * using the C calling convention, for which the arguments are never + * reversed (contrary to `extern (D)`). + */ + extern (C) bool function(in void*, in void*) xopEquals; + extern (C) int function(in void*, in void*) xopCmp; + string function(in void*) xtoString; enum StructFlags : uint { From d64e2872948f923709f777b5f30753a91854d282 Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 26 Oct 2015 14:52:11 +0100 Subject: [PATCH 2/2] extern(D): Don't reverse parameter order on x86_64 --- src/core/math.d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/math.d b/src/core/math.d index d10eb9113d..9182ae1acb 100644 --- a/src/core/math.d +++ b/src/core/math.d @@ -138,10 +138,10 @@ version (LDC) asm { naked; - push RCX; // push exp (8 bytes), passed in ECX + push RDX; // push exp (8 bytes), passed in EDX fild int ptr [RSP]; // push exp onto FPU stack - pop RCX; // return stack to initial state - fld real ptr [RDX]; // push n onto FPU stack, passed in [RDX] + pop RDX; // return stack to initial state + fld real ptr [RCX]; // push n onto FPU stack, passed in [RCX] fscale; // ST(0) = ST(0) * 2^ST(1) fstp ST(1); // pop stack maintaining top value => function return value ret; // no arguments passed via stack