changeset 545:ca28e9e3c644

- test/callback_plain_c++, to test C++ non-trivial aggrs by value, as well as method callback handlers - Changelog
author Tassilo Philipp
date Tue, 31 May 2022 18:35:06 +0200
parents 111236b31c75
children ba70fb631bea
files ChangeLog test/callback_plain_c++/CMakeLists.txt test/callback_plain_c++/Makefile.embedded test/callback_plain_c++/Makefile.generic test/callback_plain_c++/Nmakefile test/callback_plain_c++/mkfile test/callback_plain_c++/test_main.cc
diffstat 7 files changed, 287 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue May 31 18:25:13 2022 +0200
+++ b/ChangeLog	Tue May 31 18:35:06 2022 +0200
@@ -16,7 +16,7 @@
   o windows/x64/masm directives added to specify how stack unwinds (help for
     debuggers, exception handling, etc.; thanks Raphael Luba)
 dyncallback:
-  o stack unwinding debug help on windows... @@@@@@@@@@@@@@@@@@@@ (thanks Raphael Luba!)
+  o stack unwinding debug help on windows (thanks Raphael Luba!)
   o aggregate-by-value (struct, union) support for x64 (win and sysv; thanks Raphael Luba!)
   o new aggregate arg interface DCaggr
   o windows/x64/masm directives added to specify how stack unwinds (help for
@@ -29,6 +29,8 @@
   o call_suite_aggrs: new test suite for calls with aggregate arguments and
     return types (structs, unions and arrays as aggregate members)
   o callback_suite_aggrs: new test suite, like call_suite_aggrs but for callbacks
+  o plain_c++: added non-trivial C++ aggregate tests
+  o callback_plain_c++: new test, focusing on methods and non-trivial C++ aggregates
   o simplifications and refactoring to share more code (especially signature
     and case generator) across test suites
 doc:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/callback_plain_c++/CMakeLists.txt	Tue May 31 18:35:06 2022 +0200
@@ -0,0 +1,4 @@
+#
+add_executable(callback_plain_c++ test_main.c)
+target_link_libraries(callback_plain_c++ dyncallback_s dyncall_s)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/callback_plain_c++/Makefile.embedded	Tue May 31 18:35:06 2022 +0200
@@ -0,0 +1,19 @@
+APP = callback_plain_c++
+OBJS = test_main.o
+
+SRCTOP   = ../..
+BLDTOP   = ${SRCTOP}
+CFLAGS  += -I${SRCTOP}/dyncall
+LDFLAGS += -L${BLDDIR}/dyncallback
+LDLIBS  += -ldyncallback_s -ldyncall_s
+
+all: ${APP}
+
+.PHONY: all clean install
+
+${APP}: ${OBJS} 
+	${CC} ${OBJS} ${LDFLAGS} ${LDLIBS} -o ${APP} 
+
+clean:
+	rm -f ${APP} ${OBJS}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/callback_plain_c++/Makefile.generic	Tue May 31 18:35:06 2022 +0200
@@ -0,0 +1,15 @@
+APP     = callback_plain_c++
+OBJS    = test_main.o
+SRCTOP  = ${VPATH}/../..
+BLDTOP  = ../..
+CFLAGS += -I${SRCTOP}/dyncall
+LDLIBS  += -L${BLDTOP}/dyncallback -ldyncallback_s -L${BLDTOP}/dyncall -ldyncall_s
+.PHONY: all clean install
+all: ${APP}
+${APP}: ${OBJS} 
+	${CC} ${CFLAGS} ${LDFLAGS} ${OBJS} ${LDLIBS} -o ${APP}
+clean:
+	rm -f ${APP} ${OBJS}
+install:
+	mkdir -p ${PREFIX}/test
+	cp ${APP} ${PREFIX}/test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/callback_plain_c++/Nmakefile	Tue May 31 18:35:06 2022 +0200
@@ -0,0 +1,58 @@
+#//////////////////////////////////////////////////////////////////////////////
+#
+# Copyright (c) 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.
+#
+#//////////////////////////////////////////////////////////////////////////////
+
+#///////////////////////////////////////////////////
+#
+#	nmake makefile
+#	Nmakefile
+#
+#///////////////////////////////////////////////////
+
+
+TOP = ..\..
+
+!INCLUDE $(TOP)\buildsys\nmake\prolog.nmake
+
+
+!IF "$(BUILD_OS)" == "windows"
+
+TARGETS = callback_plain_c++.exe
+OBJS = test_main.obj
+
+$(TARGETS): $(OBJS)
+	echo Linking $@ ...
+	$(LD) /OUT:"$@" $(LDFLAGS) $(OBJS) $(TOP)\dyncall\dyncall_s.lib $(TOP)\dyncallback\dyncallback_s.lib
+
+
+!ELSE IF "$(BUILD_OS)" == "nds"
+
+TARGETS = callback_plain_c++.nds
+OBJS = test_main.o
+
+$(TARGETS): $(OBJS)
+	echo Linking $@ ...
+	$(LD) $(LDFLAGS) $(OBJS) $(DEVKITPRO_PATH)\libnds\lib\libnds9.a $(TOP)/dyncall/libdyncall_s.a $(TOP)\dyncallback\libdyncallback_s.a -o "$(@B).elf"
+	$(OCP) -O binary "$(@B).elf" "$(@B).arm9"
+	ndstool -c "$@" -9 "$(@B).arm9"
+	del "$(@B).elf" "$(@B).arm9"
+
+!ENDIF
+
+
+!INCLUDE $(TOP)\buildsys\nmake\epilog.nmake
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/callback_plain_c++/mkfile	Tue May 31 18:35:06 2022 +0200
@@ -0,0 +1,29 @@
+#//////////////////////////////////////////////////////////////////////////////
+#
+# Copyright (c) 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.
+#
+#//////////////////////////////////////////////////////////////////////////////
+
+
+TOP		= ../..
+<$TOP/buildsys/mk/prolog.mk
+
+
+UNITS       = test_main
+APPLICATION = callback_plain_c++
+LIBS        = $TOP/dyncallback/libdyncallback_s.a$O $TOP/dyncall/libdyncall_s.a$O
+
+
+<$TOP/buildsys/mk/epilog.mk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/callback_plain_c++/test_main.cc	Tue May 31 18:35:06 2022 +0200
@@ -0,0 +1,159 @@
+/*
+
+ Package: dyncall
+ Library: test
+ File: test/callback_plain_c++/test_main.c
+ Description:
+
+   Tests only C++ specifics:
+   - method callback handlers (= standard dyncallback handler, but testing
+     calling convention mode setting and hidden this ptr)
+   - calling functions or methods that take/return non-trivial C++ aggregates
+
+ License:
+
+   Copyright (c) 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 "../../dyncallback/dyncall_callback.h"
+#include "../common/platformInit.h"
+#include "../common/platformInit.c" /* Impl. for functions only used in this translation unit */
+
+
+#if defined(DC__Feature_AggrByVal)
+struct Triv {
+  float t;
+};
+
+struct NonTriv {
+  int i, j;
+  NonTriv(int a, int b) : i(a),j(b) { }
+  NonTriv(const NonTriv& rhs) { static int a=13, b=37; i = a++; j = b++; }
+};
+
+
+char cbNonTrivAggrArgHandler(DCCallback* cb, DCArgs* args, DCValue* result, void* userdata)
+{
+  int* ud = (int*)userdata;
+  int     arg1;
+  NonTriv arg2(0, 0);
+  NonTriv arg3(0, 0);
+  Triv    arg4;
+  double  arg5;
+
+  printf("reached callback\n");
+  printf("userdata: %d\n", *ud);
+
+  // the non-triv arg4 test basically assures that the aggr description list is
+  // respected (with first two being NULL as non-trivial aggrs)
+  arg1 = dcbArgInt(args);                   printf("1st argument: %d\n", arg1);
+  arg2 = *(NonTriv*)dcbArgAggr(args, NULL); printf("2nd argument: %d %d\n", arg2.i, arg2.j);
+  arg3 = *(NonTriv*)dcbArgAggr(args, NULL); printf("3nd argument: %d %d\n", arg3.i, arg3.j);
+  dcbArgAggr(args, (DCpointer)&arg4);       printf("4th argument: %f\n", arg4.t);
+  arg5 = dcbArgDouble(args);                printf("5th argument: %f\n", arg5);
+
+  // the non-triv aggregate members are 14, 38 and 15, 39, respectively, b/c of
+  // copy-ctor call on *passing* them to this handler (not b/c of assignment
+  // operator, above); see below on where 13 and 37 are initialized
+  result->d = *ud + arg1 + arg2.i + arg2.j + arg3.i + arg3.j + arg4.t + arg5;
+  return 'd';
+}
+
+
+int testNonTrivAggrArgsCallback()
+{
+  DCCallback* cb;
+  Triv t = { 1.75f };
+  NonTriv a(1, 2);
+  NonTriv b(a); // this sets NonTriv's statics a = 13 and b = 37
+
+  int ret = 1;
+  double result = 0;
+  int userdata = 1337;
+
+  DCaggr *triv_aggr = dcNewAggr(1, sizeof(t));
+  dcAggrField(triv_aggr, DC_SIGCHAR_FLOAT, offsetof(Triv, t), 1);
+  dcCloseAggr(triv_aggr);
+
+  DCaggr *aggrs[3] = { NULL, NULL, triv_aggr }; // NULL b/c non-trivial aggrs, see manpage
+
+  cb = dcbNewCallback2("iAAAd)d", &cbNonTrivAggrArgHandler, &userdata, aggrs);
+
+  result = ((double(*)(int, NonTriv, NonTriv, Triv, double))cb)(123, a, b, t, 4.5);
+  dcbFreeCallback(cb);
+
+  printf("successfully returned from callback\n");
+  printf("return value (should be 1572.25): %f\n", result);
+
+  ret = result == 1572.25 && ret;
+
+  return ret;
+}
+
+
+
+char cbNonTrivAggrReturnHandler(DCCallback* cb, DCArgs* args, DCValue* result, void* userdata)
+{
+  printf("reached callback\n");
+  dcbReturnAggr(args, result, NULL);    // this sets result->p to the non-triv aggr space allocated by the calling convention
+  *(NonTriv*)result->p = NonTriv(1, 3); // explicit non-copy ctor and assignment operator, so not using NonTriv's statics a and b
+
+  return 'A';
+}
+
+
+int testNonTrivAggrReturnCallback()
+{
+  int ret = 1;
+
+  {
+    DCCallback* cb;
+    DCaggr *aggrs[1] = { NULL }; // one non-triv aggr
+    cb = dcbNewCallback2(")A", &cbNonTrivAggrReturnHandler, NULL, aggrs);
+
+    NonTriv result = ((NonTriv(*)())cb)();
+
+    dcbFreeCallback(cb);
+
+    printf("successfully returned from callback\n");
+    printf("return value (should be %d %d): %d %d\n", 1, 3, result.i, result.j);
+
+    ret = result.i == 1 && result.j == 3 && ret;
+  }
+
+  return ret;
+}
+#endif
+
+
+int main()
+{
+  int result = 1;
+
+  dcTest_initPlatform();
+
+#if defined(DC__Feature_AggrByVal)
+  result = testNonTrivAggrArgsCallback() && result;
+  result = testNonTrivAggrReturnCallback() && result;
+#endif
+
+  printf("result: callback_plain_c++: %d\n", result);
+
+  dcTest_deInitPlatform();
+
+  return !result;
+}
+