# HG changeset patch # User Tassilo Philipp # Date 1654014906 -7200 # Node ID ca28e9e3c644f103c4379b264de7374104596ccf # Parent 111236b31c75e32acde18db970f3640aac628198 - test/callback_plain_c++, to test C++ non-trivial aggrs by value, as well as method callback handlers - Changelog diff -r 111236b31c75 -r ca28e9e3c644 ChangeLog --- 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: diff -r 111236b31c75 -r ca28e9e3c644 test/callback_plain_c++/CMakeLists.txt --- /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) + diff -r 111236b31c75 -r ca28e9e3c644 test/callback_plain_c++/Makefile.embedded --- /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} + diff -r 111236b31c75 -r ca28e9e3c644 test/callback_plain_c++/Makefile.generic --- /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 diff -r 111236b31c75 -r ca28e9e3c644 test/callback_plain_c++/Nmakefile --- /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 +# +# 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 + diff -r 111236b31c75 -r ca28e9e3c644 test/callback_plain_c++/mkfile --- /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 +# +# 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 diff -r 111236b31c75 -r ca28e9e3c644 test/callback_plain_c++/test_main.cc --- /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 + + 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; +} +