comparison test/plain_c++/test_main.cc @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children e63089fe5bef
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
1 /*
2
3 Package: dyncall
4 Library: test
5 File: test/plain_c++/test_main.cc
6 Description:
7 License:
8
9 Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>,
10 Tassilo Philipp <tphilipp@potion-studios.com>
11
12 Permission to use, copy, modify, and distribute this software for any
13 purpose with or without fee is hereby granted, provided that the above
14 copyright notice and this permission notice appear in all copies.
15
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
24 */
25
26
27
28
29 #include "test_framework.h"
30 #include "../../dyncall/dyncall.h"
31 #include "../common/platformInit.h"
32 #include "../common/platformInit.c" /* Impl. for functions only used in this translation unit */
33
34
35 /* -------------------------------------------------------------------------
36 * test: identity function calls
37 * ------------------------------------------------------------------------- */
38
39 #define DEF_FUNCS(API,NAME) \
40 void API fun_##NAME##_v() { } \
41 DCbool API fun_##NAME##_b(DCbool x) { return x; } \
42 DCint API fun_##NAME##_i(DCint x) { return x; } \
43 DClong API fun_##NAME##_j(DClong x) { return x; } \
44 DClonglong API fun_##NAME##_l(DClonglong x) { return x; } \
45 DCfloat API fun_##NAME##_f(DCfloat x) { return x; } \
46 DCdouble API fun_##NAME##_d(DCdouble x) { return x; } \
47 DCpointer API fun_##NAME##_p(DCpointer x) { return x; }
48
49 /* __cdecl */
50
51 #if !defined(DC__OS_Win32)
52 # define __declspec(X)
53 # define __cdecl
54 #endif
55
56
57 /* -------------------------------------------------------------------------
58 * test: identity this calls
59 * ------------------------------------------------------------------------- */
60
61 union ValueUnion
62 {
63 DCbool B;
64 DCint i;
65 DClong j;
66 DClonglong l;
67 DCfloat f;
68 DCdouble d;
69 DCpointer p;
70 };
71
72 /* C++ class using __cdecl this call */
73
74 // #define VTBI_DESTRUCTOR 0
75
76 /*
77 * the layout of the VTable is non-standard and it is not clear what is the initial real first method index.
78 * so for it turns out that:
79 * on vc/x86 : 1
80 * on GCC/x86 : 2
81 */
82
83 #if defined DC__C_MSVC
84 #define VTBI_BASE 1
85 #else
86 #define VTBI_BASE 2
87 #endif
88
89 #define VTBI_SET_BOOL VTBI_BASE+0
90 #define VTBI_GET_BOOL VTBI_BASE+1
91 #define VTBI_SET_INT VTBI_BASE+2
92 #define VTBI_GET_INT VTBI_BASE+3
93 #define VTBI_SET_LONG VTBI_BASE+4
94 #define VTBI_GET_LONG VTBI_BASE+5
95 #define VTBI_SET_LONG_LONG VTBI_BASE+6
96 #define VTBI_GET_LONG_LONG VTBI_BASE+7
97 #define VTBI_SET_FLOAT VTBI_BASE+8
98 #define VTBI_GET_FLOAT VTBI_BASE+9
99 #define VTBI_SET_DOUBLE VTBI_BASE+10
100 #define VTBI_GET_DOUBLE VTBI_BASE+11
101 #define VTBI_SET_POINTER VTBI_BASE+12
102 #define VTBI_GET_POINTER VTBI_BASE+13
103
104 class Value
105 {
106 public:
107 virtual ~Value() {}
108
109 virtual void __cdecl setBool(DCbool x) { mValue.B = x; }
110 virtual DCbool __cdecl getBool() { return mValue.B; }
111 virtual void __cdecl setInt(DCint x) { mValue.i = x; }
112 virtual DCint __cdecl getInt() { return mValue.i; }
113 virtual void __cdecl setLong(DClong x) { mValue.j = x; }
114 virtual DClong __cdecl getLong() { return mValue.j; }
115 virtual void __cdecl setLongLong(DClonglong x) { mValue.l = x; }
116 virtual DClonglong __cdecl getLongLong() { return mValue.l; }
117 virtual void __cdecl setFloat(DCfloat x) { mValue.f = x; }
118 virtual DCfloat __cdecl getFloat() { return mValue.f; }
119 virtual void __cdecl setDouble(DCdouble x) { mValue.d = x; }
120 virtual DCdouble __cdecl getDouble() { return mValue.d; }
121 virtual void __cdecl setPtr(DCpointer x) { mValue.p = x; }
122 virtual DCpointer __cdecl getPtr() { return mValue.p; }
123 private:
124 ValueUnion mValue;
125 };
126
127 /* C++ class using (on win32: microsoft) this call */
128
129 class ValueMS
130 {
131 public:
132 virtual ~ValueMS() {}
133
134 virtual void setBool(DCbool x) { mValue.B = x; }
135 virtual DCbool getBool() { return mValue.B; }
136 virtual void setInt(DCint x) { mValue.i = x; }
137 virtual DCint getInt() { return mValue.i; }
138 virtual void setLong(DClong x) { mValue.j = x; }
139 virtual DClong getLong() { return mValue.j; }
140 virtual void setLongLong(DClonglong x) { mValue.l = x; }
141 virtual DClonglong getLongLong() { return mValue.l; }
142 virtual void setFloat(DCfloat x) { mValue.f = x; }
143 virtual DCfloat getFloat() { return mValue.f; }
144 virtual void setDouble(DCdouble x) { mValue.d = x; }
145 virtual DCdouble getDouble() { return mValue.d; }
146 virtual void setPtr(DCpointer x) { mValue.p = x; }
147 virtual DCpointer getPtr() { return mValue.p; }
148 private:
149 ValueUnion mValue;
150 };
151
152 template<typename T>
153 void testCallValue(DCCallVM* pc)
154 {
155 T o;
156 T* pThis = &o;
157 DCpointer* vtbl = *( (DCpointer**) pThis ); /* vtbl is located at beginning of class */
158
159 /* set/get bool (TRUE) */
160
161 dcReset(pc);
162 dcArgPointer(pc, pThis);
163 dcArgBool(pc,DC_TRUE);
164 dcCallVoid(pc, vtbl[VTBI_SET_BOOL] );
165 dcReset(pc);
166 dcArgPointer(pc, pThis);
167 DC_TEST( dcCallBool(pc, vtbl[VTBI_GET_BOOL] ) == DC_TRUE );
168 /* set/get bool (FALSE) */
169
170 dcReset(pc);
171 dcArgPointer(pc, pThis);
172 dcArgBool(pc,DC_FALSE);
173 dcCallVoid(pc, vtbl[VTBI_SET_BOOL] );
174 dcReset(pc);
175 dcArgPointer(pc, pThis);
176 DC_TEST( dcCallBool(pc, vtbl[VTBI_GET_BOOL] ) == DC_FALSE );
177
178 /* set/get int */
179
180 dcReset(pc);
181 dcArgPointer(pc, pThis);
182 dcArgInt(pc,1234);
183 dcCallVoid(pc, vtbl[VTBI_SET_INT] );
184 dcReset(pc);
185 dcArgPointer(pc, pThis);
186 DC_TEST( dcCallInt(pc, vtbl[VTBI_GET_INT] ) == 1234 );
187
188 /* set/get long */
189
190 dcReset(pc);
191 dcArgPointer(pc, pThis);
192 dcArgLong(pc,0xCAFEBABEUL);
193 dcCallVoid(pc, vtbl[VTBI_SET_LONG] );
194 dcReset(pc);
195 dcArgPointer(pc, pThis);
196 DC_TEST( dcCallLong(pc, vtbl[VTBI_GET_LONG] ) == (DClong)0xCAFEBABEUL );
197
198 /* set/get long long */
199
200 dcReset(pc);
201 dcArgPointer(pc, pThis);
202 dcArgLongLong(pc,0xCAFEBABEDEADC0DELL);
203 dcCallVoid(pc, vtbl[VTBI_SET_LONG_LONG] );
204 dcReset(pc);
205 dcArgPointer(pc, pThis);
206 DC_TEST( dcCallLongLong(pc, vtbl[VTBI_GET_LONG_LONG] ) == (DClonglong)0xCAFEBABEDEADC0DELL );
207
208 /* set/get float */
209
210 dcReset(pc);
211 dcArgPointer(pc, pThis);
212 dcArgFloat(pc,1.2345f);
213 dcCallVoid(pc, vtbl[VTBI_SET_FLOAT] );
214 dcReset(pc);
215 dcArgPointer(pc, pThis);
216 DC_TEST( dcCallFloat(pc, vtbl[VTBI_GET_FLOAT] ) == 1.2345f );
217
218 /* set/get double */
219
220 dcReset(pc);
221 dcArgPointer(pc, pThis);
222 dcArgDouble(pc,1.23456789);
223 dcCallVoid(pc, vtbl[VTBI_SET_DOUBLE] );
224 dcReset(pc);
225 dcArgPointer(pc, pThis);
226 DC_TEST( dcCallDouble(pc, vtbl[VTBI_GET_DOUBLE] ) == 1.23456789 );
227
228 /* set/get pointer */
229
230 dcReset(pc);
231 dcArgPointer(pc, pThis);
232 dcArgPointer(pc, (DCpointer) 0xCAFEBABE );
233 dcCallVoid(pc, vtbl[VTBI_SET_POINTER] );
234 dcReset(pc);
235 dcArgPointer(pc, pThis);
236 DC_TEST( dcCallPointer(pc, vtbl[VTBI_GET_POINTER] ) == ( (DCpointer) 0xCAFEBABE ) );
237 }
238
239
240 #ifdef DC__OS_Win32
241
242 DC_DEFINE_TEST_FUNC_BEGIN(testCallThisMS)
243
244 DCCallVM* pc = dcNewCallVM(4096);
245 dcMode(pc,DC_CALL_C_X86_WIN32_THIS_MS);
246 dcReset(pc);
247 testCallValue<ValueMS>(pc);
248 dcFree(pc);
249
250 DC_DEFINE_TEST_FUNC_END
251
252 #endif
253
254
255 DC_DEFINE_TEST_FUNC_BEGIN(testCallThisC)
256
257 DCCallVM* pc = dcNewCallVM(4096);
258 dcReset(pc);
259 testCallValue<Value>(pc);
260 dcFree(pc);
261
262 DC_DEFINE_TEST_FUNC_END
263
264
265 extern "C" {
266
267 int main(int argc, char* argv[])
268 {
269 dcTest_initPlatform();
270
271 int b = TRUE;
272
273 #if defined(DC__OS_Win32) // ThisCall temporarily only for win 32 @@@
274
275 b = b && testCallThisC();
276 printf("ThisC:%d\n",b);
277
278 #if defined(DC__C_MSVC)
279 b = b && testCallThisMS();
280 printf("ThisMS:%d\n",b);
281 #endif
282
283 #endif
284
285 printf("result: plain_cpp: %d\n", b);
286
287 dcTest_deInitPlatform();
288
289 return !b;
290 }
291
292 } // extern "C"
293