1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is js-ctypes.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * The Mozilla Foundation <http://www.mozilla.org/>.
19 : * Portions created by the Initial Developer are Copyright (C) 2009
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Fredrik Larsson <nossralf@gmail.com>
24 : * Mark Finkle <mark.finkle@gmail.com>, <mfinkle@mozilla.com>
25 : * Dan Witte <dwitte@mozilla.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "jsctypes-test.h"
42 : #include "nsCRTGlue.h"
43 : #include <math.h>
44 : #include <stdarg.h>
45 :
46 : template <typename T> struct ValueTraits {
47 31 : static T literal() { return static_cast<T>(109.25); }
48 800 : static T sum(T a, T b) { return a + b; }
49 58 : static T sum_many(
50 : T a, T b, T c, T d, T e, T f, T g, T h, T i,
51 : T j, T k, T l, T m, T n, T o, T p, T q, T r)
52 : {
53 58 : return a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r;
54 : }
55 : };
56 :
57 : template <> struct ValueTraits<bool> {
58 : typedef bool T;
59 1 : static T literal() { return true; }
60 20 : static T sum(T a, T b) { return a || b; }
61 2 : static T sum_many(
62 : T a, T b, T c, T d, T e, T f, T g, T h, T i,
63 : T j, T k, T l, T m, T n, T o, T p, T q, T r)
64 : {
65 : return a || b || c || d || e || f || g || h || i ||
66 2 : j || k || l || m || n || o || p || q || r;
67 : }
68 : };
69 :
70 : void
71 2 : test_void_t_cdecl()
72 : {
73 : // do nothing
74 : return;
75 : }
76 :
77 : #define FUNCTION_TESTS(name, type, ffiType, suffix) \
78 : type ABI \
79 : get_##name##_##suffix() \
80 : { \
81 : return ValueTraits<type>::literal(); \
82 : } \
83 : \
84 : type ABI \
85 : set_##name##_##suffix(type x) \
86 : { \
87 : return x; \
88 : } \
89 : \
90 : type ABI \
91 : sum_##name##_##suffix(type x, type y) \
92 : { \
93 : return ValueTraits<type>::sum(x, y); \
94 : } \
95 : \
96 : type ABI \
97 : sum_alignb_##name##_##suffix(char a, type x, char b, type y, char c) \
98 : { \
99 : return ValueTraits<type>::sum(x, y); \
100 : } \
101 : \
102 : type ABI \
103 : sum_alignf_##name##_##suffix(float a, type x, float b, type y, float c) \
104 : { \
105 : return ValueTraits<type>::sum(x, y); \
106 : } \
107 : \
108 : type ABI \
109 : sum_many_##name##_##suffix( \
110 : type a, type b, type c, type d, type e, type f, type g, type h, type i, \
111 : type j, type k, type l, type m, type n, type o, type p, type q, type r) \
112 : { \
113 : return ValueTraits<type>::sum_many(a, b, c, d, e, f, g, h, i, \
114 : j, k, l, m, n, o, p, q, r); \
115 : }
116 :
117 : #define ABI /* cdecl */
118 : #define DEFINE_TYPE(x, y, z) FUNCTION_TESTS(x, y, z, cdecl)
119 : #include "typedefs.h"
120 : #undef ABI
121 :
122 : #if defined(_WIN32)
123 :
124 : void NS_STDCALL
125 : test_void_t_stdcall()
126 : {
127 : // do nothing
128 : return;
129 : }
130 :
131 : #define ABI NS_STDCALL
132 : #define DEFINE_TYPE(x, y, z) FUNCTION_TESTS(x, y, z, stdcall)
133 : #include "typedefs.h"
134 : #undef ABI
135 :
136 : #endif /* defined(_WIN32) */
137 :
138 : #define DEFINE_TYPE(name, type, ffiType) \
139 : struct align_##name { \
140 : char x; \
141 : type y; \
142 : }; \
143 : struct nested_##name { \
144 : char a; \
145 : align_##name b; \
146 : char c; \
147 : }; \
148 : \
149 : void \
150 : get_##name##_stats(size_t* align, size_t* size, size_t* nalign, size_t* nsize, \
151 : size_t offsets[]) \
152 : { \
153 : *align = offsetof(align_##name, y); \
154 : *size = sizeof(align_##name); \
155 : *nalign = offsetof(nested_##name, b); \
156 : *nsize = sizeof(nested_##name); \
157 : offsets[0] = offsetof(align_##name, y); \
158 : offsets[1] = offsetof(nested_##name, b); \
159 : offsets[2] = offsetof(nested_##name, c); \
160 : }
161 : #include "typedefs.h"
162 :
163 : template <typename T>
164 4 : PRInt32 StrLen(const T* string)
165 : {
166 : const T *end;
167 4 : for (end = string; *end; ++end);
168 4 : return end - string;
169 : }
170 :
171 : PRInt32
172 3 : test_ansi_len(const char* string)
173 : {
174 3 : return StrLen(string);
175 : }
176 :
177 : PRInt32
178 1 : test_wide_len(const PRUnichar* string)
179 : {
180 1 : return StrLen(string);
181 : }
182 :
183 : const char *
184 1 : test_ansi_ret()
185 : {
186 1 : return "success";
187 : }
188 :
189 : const PRUnichar *
190 1 : test_wide_ret()
191 : {
192 : static const PRUnichar kSuccess[] = {'s', 'u', 'c', 'c', 'e', 's', 's', '\0'};
193 1 : return kSuccess;
194 : }
195 :
196 : char *
197 2 : test_ansi_echo(const char* string)
198 : {
199 2 : return (char*)string;
200 : }
201 :
202 : PRInt32
203 2 : test_pt_in_rect(RECT rc, POINT pt)
204 : {
205 2 : if (pt.x < rc.left || pt.x > rc.right)
206 1 : return 0;
207 1 : if (pt.y < rc.bottom || pt.y > rc.top)
208 0 : return 0;
209 1 : return 1;
210 : }
211 :
212 : void
213 1 : test_init_pt(POINT* pt, PRInt32 x, PRInt32 y)
214 : {
215 1 : pt->x = x;
216 1 : pt->y = y;
217 1 : }
218 :
219 : PRInt32
220 1 : test_nested_struct(NESTED n)
221 : {
222 1 : return PRInt32(n.n1 + n.n2 + n.inner.i1 + n.inner.i2 + n.inner.i3 + n.n3 + n.n4);
223 : }
224 :
225 : POINT
226 1 : test_struct_return(RECT r)
227 : {
228 : POINT p;
229 1 : p.x = r.left; p.y = r.top;
230 : return p;
231 : }
232 :
233 : RECT
234 1 : test_large_struct_return(RECT a, RECT b)
235 : {
236 : RECT r;
237 1 : r.left = a.left; r.right = a.right;
238 1 : r.top = b.top; r.bottom = b.bottom;
239 : return r;
240 : }
241 :
242 : ONE_BYTE
243 1 : test_1_byte_struct_return(RECT r)
244 : {
245 : ONE_BYTE s;
246 1 : s.a = r.top;
247 : return s;
248 : }
249 :
250 : TWO_BYTE
251 1 : test_2_byte_struct_return(RECT r)
252 : {
253 : TWO_BYTE s;
254 1 : s.a = r.top;
255 1 : s.b = r.left;
256 : return s;
257 : }
258 :
259 : THREE_BYTE
260 1 : test_3_byte_struct_return(RECT r)
261 : {
262 : THREE_BYTE s;
263 1 : s.a = r.top;
264 1 : s.b = r.left;
265 1 : s.c = r.bottom;
266 : return s;
267 : }
268 :
269 : FOUR_BYTE
270 1 : test_4_byte_struct_return(RECT r)
271 : {
272 : FOUR_BYTE s;
273 1 : s.a = r.top;
274 1 : s.b = r.left;
275 1 : s.c = r.bottom;
276 1 : s.d = r.right;
277 : return s;
278 : }
279 :
280 : FIVE_BYTE
281 1 : test_5_byte_struct_return(RECT r)
282 : {
283 : FIVE_BYTE s;
284 1 : s.a = r.top;
285 1 : s.b = r.left;
286 1 : s.c = r.bottom;
287 1 : s.d = r.right;
288 1 : s.e = r.top;
289 : return s;
290 : }
291 :
292 : SIX_BYTE
293 1 : test_6_byte_struct_return(RECT r)
294 : {
295 : SIX_BYTE s;
296 1 : s.a = r.top;
297 1 : s.b = r.left;
298 1 : s.c = r.bottom;
299 1 : s.d = r.right;
300 1 : s.e = r.top;
301 1 : s.f = r.left;
302 : return s;
303 : }
304 :
305 : SEVEN_BYTE
306 1 : test_7_byte_struct_return(RECT r)
307 : {
308 : SEVEN_BYTE s;
309 1 : s.a = r.top;
310 1 : s.b = r.left;
311 1 : s.c = r.bottom;
312 1 : s.d = r.right;
313 1 : s.e = r.top;
314 1 : s.f = r.left;
315 1 : s.g = r.bottom;
316 : return s;
317 : }
318 :
319 : void *
320 1 : test_fnptr()
321 : {
322 1 : return (void*)(uintptr_t)test_ansi_len;
323 : }
324 :
325 : PRInt32
326 3 : test_closure_cdecl(PRInt8 i, test_func_ptr f)
327 : {
328 3 : return f(i);
329 : }
330 :
331 : #if defined(_WIN32)
332 : PRInt32
333 : test_closure_stdcall(PRInt8 i, test_func_ptr_stdcall f)
334 : {
335 : return f(i);
336 : }
337 : #endif /* defined(_WIN32) */
338 :
339 : template <typename T> struct PromotedTraits {
340 : typedef T type;
341 : };
342 : #define DECL_PROMOTED(FROM, TO) \
343 : template <> struct PromotedTraits<FROM> { \
344 : typedef TO type; \
345 : }
346 : DECL_PROMOTED(bool, int);
347 : DECL_PROMOTED(char, int);
348 : DECL_PROMOTED(short, int);
349 :
350 : PRInt32
351 2 : test_sum_va_cdecl(PRUint8 n, ...)
352 : {
353 : va_list list;
354 2 : PRInt32 sum = 0;
355 2 : va_start(list, n);
356 13 : for (PRUint8 i = 0; i < n; ++i)
357 11 : sum += va_arg(list, PromotedTraits<PRInt32>::type);
358 2 : va_end(list);
359 2 : return sum;
360 : }
361 :
362 : PRUint8
363 0 : test_count_true_va_cdecl(PRUint8 n, ...)
364 : {
365 : va_list list;
366 0 : PRUint8 count = 0;
367 0 : va_start(list, n);
368 0 : for (PRUint8 i = 0; i < n; ++i)
369 0 : if (va_arg(list, PromotedTraits<bool>::type))
370 0 : count += 1;
371 0 : va_end(list);
372 0 : return count;
373 : }
374 :
375 : void
376 1 : test_add_char_short_int_va_cdecl(PRUint32* result, ...)
377 : {
378 : va_list list;
379 1 : va_start(list, result);
380 1 : *result += va_arg(list, PromotedTraits<char>::type);
381 1 : *result += va_arg(list, PromotedTraits<short>::type);
382 1 : *result += va_arg(list, PromotedTraits<int>::type);
383 1 : va_end(list);
384 1 : }
385 :
386 : PRInt32*
387 1 : test_vector_add_va_cdecl(PRUint8 num_vecs,
388 : PRUint8 vec_len,
389 : PRInt32* result, ...)
390 : {
391 : va_list list;
392 1 : va_start(list, result);
393 : PRUint8 i;
394 4 : for (i = 0; i < vec_len; ++i)
395 3 : result[i] = 0;
396 3 : for (i = 0; i < num_vecs; ++i) {
397 2 : PRInt32* vec = va_arg(list, PRInt32*);
398 8 : for (PRUint8 j = 0; j < vec_len; ++j)
399 6 : result[j] += vec[j];
400 : }
401 1 : va_end(list);
402 1 : return result;
403 : }
404 :
405 : RECT data_rect = { -1, -2, 3, 4 };
406 :
|