diff dyncall/dyncall_aggregate.c @ 533:71c884e610f0

- integration of patches from Raphael Luba, Thekla, Inc.: * integration of aggregate-by-value (struct, union) support patch for x64 (win and sysv) * windows/x64 asm additions to specify how stack unwinds (help for debuggers, exception handling, etc.) * see Changelog for details - new calling convention modes for thiscalls (platform agnostic, was specific before) * new signature character for platform agnostic thiscalls ('*' / DC_SIGCHAR_CC_THISCALL) - dcCallF(), dcVCallF(), dcArgF() and dcVArgF(): * added support for aggregates-by-value (wasn't part of patch) * change that those functions don't implicitly call dcReset() anymore, which was unflexible (breaking change) - added macros to feature test implementation for aggregate-by-value and syscall support - changed libdyncall_s.lib and libdyncallback_s.lib order in callback test makefiles, as some toolchains are picky about order - doc: * man page updates to describe aggregate interface * manual overview changes to highlight platforms with aggregate-by-value support - test/plain: replaced tests w/ old/stale sctruct interface with new aggregate one
author Tassilo Philipp
date Thu, 21 Apr 2022 13:35:47 +0200
parents
children ba70fb631bea
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dyncall/dyncall_aggregate.c	Thu Apr 21 13:35:47 2022 +0200
@@ -0,0 +1,104 @@
+/*
+
+ Package: dyncall
+ Library: dyncall
+ File: dyncall/dyncall_aggregate.c
+ Description: C interface to compute struct size
+ License:
+
+   Copyright (c) 2021-2022 Tassilo Philipp <tphilipp@potion-studios.com>
+
+   Permission to use, copy, modify, and distribute this software for any
+   purpose with or without fee is hereby granted, provided that the above
+   copyright notice and this permission notice appear in all copies.
+
+   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+
+
+
+#include "dyncall.h"
+#include "dyncall_signature.h"
+#include "dyncall_aggregate.h"
+#include "dyncall_alloc.h"
+#include <stdio.h>
+#include <assert.h>
+#include <stdarg.h>
+
+
+
+#if defined(DC__Arch_AMD64) && defined(DC_UNIX)
+#  include "dyncall_aggregate_x64.c"
+#else
+static void dcFinishAggr(DCaggr *ag)
+{
+}
+#endif
+
+
+DCaggr* dcNewAggr(DCsize maxFieldCount, DCsize size)
+{
+	DCaggr* ag = (DCaggr*)dcAllocMem(sizeof(DCaggr) + maxFieldCount * sizeof(DCfield));
+	ag->n_fields = 0;
+	ag->size = size;
+	return ag;
+}
+
+
+void dcAggrField(DCaggr* ag, DCsigchar type, DCint offset, DCsize array_len, ...)
+{
+	DCfield *f = ag->fields + (ag->n_fields++);
+	f->type = type;
+	f->offset = offset;
+	f->array_len = array_len;
+	f->sub_aggr = NULL;
+	switch(type) {
+		case DC_SIGCHAR_BOOL:       f->size = sizeof(DCbool);     break;
+		case DC_SIGCHAR_CHAR:       
+		case DC_SIGCHAR_UCHAR:      f->size = sizeof(DCchar);     break;
+		case DC_SIGCHAR_SHORT:      
+		case DC_SIGCHAR_USHORT:     f->size = sizeof(DCshort);    break;
+		case DC_SIGCHAR_INT:        
+		case DC_SIGCHAR_UINT:       f->size = sizeof(DCint);      break;
+		case DC_SIGCHAR_LONG:       
+		case DC_SIGCHAR_ULONG:      f->size = sizeof(DClong);     break;
+		case DC_SIGCHAR_LONGLONG:   
+		case DC_SIGCHAR_ULONGLONG:  f->size = sizeof(DClonglong); break;
+		case DC_SIGCHAR_FLOAT:      f->size = sizeof(DCfloat);    break;
+		case DC_SIGCHAR_DOUBLE:     f->size = sizeof(DCdouble);   break;
+		case DC_SIGCHAR_POINTER:
+		case DC_SIGCHAR_STRING:     f->size = sizeof(DCpointer);  break;
+		case DC_SIGCHAR_AGGREGATE:
+		{
+			va_list ap;
+			va_start(ap, array_len);
+			f->sub_aggr = va_arg(ap, const DCaggr*);
+			va_end(ap);
+
+			f->size = f->sub_aggr->size;
+			break;
+		}
+		default:
+			assert(0);
+	}
+}
+
+
+void dcCloseAggr(DCaggr* ag)
+{
+	dcFinishAggr(ag);
+}
+
+
+void dcFreeAggr(DCaggr* ag)
+{
+	dcFreeMem(ag);
+}
+