Mercurial > pub > dyncall > dyncall
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 |