comparison dyncall/dyncall_callvm_x64.c @ 546:ba70fb631bea

x64: * support for non-standard aggr-by-value packing (#pragma pack, etc.) * callbacks: handling callconv prefixes in signature
author Tassilo Philipp
date Tue, 31 May 2022 19:29:34 +0200
parents 71c884e610f0
children a93bb23fca8c
comparison
equal deleted inserted replaced
545:ca28e9e3c644 546:ba70fb631bea
166 { 166 {
167 int i; 167 int i;
168 DCCallVM_x64* self = (DCCallVM_x64*)in_self; 168 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
169 169
170 if (!ag) { 170 if (!ag) {
171 /* non-trivial aggrs (C++) are passed via pointer (win and sysv callconv), 171 /* non-trivial aggrs (C++) are passed via pointer (win and sysv callconv),
172 * copy has to be provided by user, as dyncall cannot do such copies*/ 172 * copy has to be provided by user, as dyncall cannot do such copies*/
173 dc_callvm_argPointer_x64(in_self, (DCpointer)x); 173 dc_callvm_argPointer_x64(in_self, (DCpointer)x);
174 return; 174 return;
175 } 175 }
176 176
177 #if defined(DC_UNIX) 177 #if defined(DC_UNIX)
252 252
253 assert(self->mRegCount.i == 0 && self->mRegCount.f == 0 && "dc_callvm_begin_aggr_x64 should be called before any function arguments are declared"); 253 assert(self->mRegCount.i == 0 && self->mRegCount.f == 0 && "dc_callvm_begin_aggr_x64 should be called before any function arguments are declared");
254 #if defined(DC_UNIX) 254 #if defined(DC_UNIX)
255 if (!ag || (ag->sysv_classes[0] == SYSVC_MEMORY)) { 255 if (!ag || (ag->sysv_classes[0] == SYSVC_MEMORY)) {
256 #else 256 #else
257 if (!ag || ag->size > 8) { 257 if (!ag || ag->size > 8 || /*not a power of 2?*/(ag->size & (ag->size - 1)))
258 #endif 258 #endif
259 /* pass pointer to aggregate as hidden first argument */ 259 /* pass pointer to aggregate as hidden first argument */
260 self->mAggrReturnReg = 0; 260 self->mAggrReturnReg = 0;
261 } 261 }
262 } 262 }
267 { 267 {
268 DCCallVM_x64* self = (DCCallVM_x64*)in_self; 268 DCCallVM_x64* self = (DCCallVM_x64*)in_self;
269 269
270 assert(self->mRegCount.i == 0 && self->mRegCount.f == 0 && "dc_callvm_begin_aggr_x64_win64_this should be called before any function arguments are declared"); 270 assert(self->mRegCount.i == 0 && self->mRegCount.f == 0 && "dc_callvm_begin_aggr_x64_win64_this should be called before any function arguments are declared");
271 271
272 if (!ag || ag->size > 8) { 272 /* thiscall: this-ptr comes first, then pointer to aggregate as hidden (second) argument */
273 /* thiscall: this-ptr comes first, then pointer to aggregate as hidden (second) argument */ 273 self->mAggrReturnReg = 1;
274 self->mAggrReturnReg = 1;
275 }
276 } 274 }
277 #endif 275 #endif
278 276
279 277
280 static void dc_callvm_call_x64_aggr(DCCallVM* in_self, DCpointer target, const DCaggr *ag, DCpointer ret) 278 static void dc_callvm_call_x64_aggr(DCCallVM* in_self, DCpointer target, const DCaggr *ag, DCpointer ret)