1 /*
2 Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24 /*
25 * jtie_gcalls.hpp
26 */
27
28 #ifndef jtie_gcalls_hpp
29 #define jtie_gcalls_hpp
30
31 #include "jtie_stdint.h"
32 #include "jtie_tconv_impl.hpp"
33 #include "jtie_tconv_object_impl.hpp"
34 #include "helpers.hpp"
35
36 // ---------------------------------------------------------------------------
37 // generic wrapper function definitions
38 // ---------------------------------------------------------------------------
39
40 // XXX document workaround for MSVC's problems with template disambiguation:
41 // gcall -> gcall_fr, gcall_fv, gcall_mfr, gcall_mfv
42
43 // XXX update comments below on alternate handling of const member functions
44
45 // Design and Implementation Notes:
46 //
47 // - The function templates (gcall<...>() et al) in this file implement
48 // generically the delegation of Java method calls to C++ functions.
49 //
50 // While the template definitions are schematic, they are quite numerous.
51 // For example, to support up to 10-ary functions, 60 + 6 + 1 = 67 wrapper
52 // template definitions need to written (plus 11 + 1 for c'tor, d'tor).
53 //
54 // Therefore, preprocessor macros are used below for generating the
55 // n-ary template definitions allowing for drastically cutting down the
56 // code to the basic patterns -- at the expense of readability, however.
57 //
58 // - The templates' type parameters allow to abstract from the formal types
59 // of parameters, result, and object invocation target. The diverse data
60 // conversions between the actual Java and C++ parameters are carried out
61 // by the classes Param<>, Result<>, and Target<>, respectively.
62 //
63 // - In contrast, it's more difficult to abstract from the number of
64 // parameters using templates for maximum compile-time computation.
65 // Other options:
66 // - variadic templates: not in the C++ standard yet
67 // - using template tuple (or recursive list) types to assemble the call
68 // arguments into a single compile-time data structure: poses code upon
69 // the caller, especially, when having to specify the full signature
70 // of the C function as template arguments
71 //
72 // - In addition, by the C++ rules on matching formal and actual template
73 // paramters for function types, *six* separate, "overloaded" definitions
74 // are needed for each n-ary wrapper function template:
75 //
76 // Category: Template Parameter Signature:
77 // 1 global functions
78 // 1.1 w/o return: void F(...)
79 // 1.2 w/ return: RT::CF_t F(...)
80 // 2 static member functions
81 // 2.1 w/o return: same as 1.1
82 // 2.2 w/ return: same as 1.2
83 // 3 non-static member functions
84 // 3.1 non-const member
85 // 3.1.1 w/o return: void (OT::CF_t::*F)(...)
86 // 3.1.2 w/ return: RT::CF_t (OT::CF_t::*F)(...)
87 // 3.2 const member
88 // 3.2.1 w/o return: void (OT::CF_t::*F)(...) const
89 // 3.2.2 w/ return: RT::CF_t (OT::CF_t::*F)(...) const
90 //
91 // Other options:
92 // - 'void' can be used as argument for a formal template type parameter,
93 // collapsing the const/non-const patterns: works only in simple cases,
94 // not with code/return stmts for Java-C++ parameter/result conversions
95 //
96 // - Introduce a C function call wrapper class templates that abstract from
97 // the signature differences hiding them from the gcall<...>() functions:
98 // poses code upon the caller to construct the C call wrapper type with
99 // the list all the C function's return/parameter types.
100 //
101 // - Target objects are internally (OT::CA_t) hold by reference (they must
102 // not be null, which Target<> checks during JA_t -> CA_t conversion).
103 // Hence, the code below applies a pointer-to-function-member
104 // (cao.*F)() -- on object
105 // [(cao->*F)() -- on pointer-to-object, if held as pointer]
106 //
107 // - One must be careful not to trigger any copy-constructing at explicit
108 // type casts between an object (result) from the C formal to the actual
109 // type (e.g., A & -> A) using the cast<> function template, e.g.:
110 // cast< typename OT::CF_t, typename OT::CA_t >(cao)
111 // cast< typename P0T::CF_t, typename P0T::CA_t >(cap0)
112 // ...
113 //
114 // However, this issue is moot now, since all casts between the formal
115 // and actual C types were removed under the requirement that these types
116 // have to be assignment compatible.
117 //
118 // An application is not affected when using the mapping as generated
119 // by the pre-defined macro
120 // define_class_mapping( J, C )
121 // for user-defined classes.
122 //
123 // - Generic wrapper functions gcreate<>() and gdelete<>() are provided that
124 // allow calling C++ constructors and destructors. Unlike the gcall<>()
125 // wrapper function template, the gcreate/gdelete do not take the name of
126 // a C++ function as template parameter, since constructors/destructors
127 // do not have a (member) name and cannot be passed as template arguments.
128 //
129 // To be able to invoke and map to constructors/destructors through the
130 // same framework used for ordinary functions, internal low-level wrapper
131 // class templates ConstructorX/Destructor are defined with raw C++
132 // arguments/results, to which gcreate<>() and gdelete<>() delegate.
133 // (Cannot use function templates here, for need of partial specialization.)
134 //
135 // The internal ConstructorX/Destructor wrappers provide the result or
136 // parameter as both, reference or pointer types.
137 //
138 // This way, the application can choose between a reference or pointer
139 // type mapping of the result/parameter (reference conversion checking
140 // for NULL and rasing a proper Java exception).
141
142 // ---------------------------------------------------------------------------
143 // List Generation Macros
144 // ---------------------------------------------------------------------------
145
146 // a macro used as element in a list; the argument is expanded, e.g.
147 // #define MY_MACRO(n) a##n
148 // LE(MY_MACRO(3)) --> a3
149 #define LE(x) x
150
151 // a macro generating a blank-separated list
152 //
153 // usage: pass the name of a macro taking a number argument, e.g.
154 // #define MY_MACRO(n) a##n
155 // BSL0(MY_MACRO) -->
156 // BSL1(MY_MACRO) --> a1
157 // BSL2(MY_MACRO) --> a1 a2
158 #define BSL0(m)
159 #define BSL1(m) LE(m(1))
160 #define BSL2(m) BSL1(m) LE(m(2))
161 #define BSL3(m) BSL2(m) LE(m(3))
162 #define BSL4(m) BSL3(m) LE(m(4))
163 #define BSL5(m) BSL4(m) LE(m(5))
164 #define BSL6(m) BSL5(m) LE(m(6))
165 #define BSL7(m) BSL6(m) LE(m(7))
166 #define BSL8(m) BSL7(m) LE(m(8))
167 #define BSL9(m) BSL8(m) LE(m(9))
168 #define BSL10(m) BSL9(m) LE(m(10))
169 #define BSL11(m) BSL10(m) LE(m(11))
170 #define BSL12(m) BSL11(m) LE(m(12))
171 #define BSL13(m) BSL12(m) LE(m(13))
172 #define BSL14(m) BSL13(m) LE(m(14))
173 #define BSL15(m) BSL14(m) LE(m(15))
174 #define BSL16(m) BSL15(m) LE(m(16))
175 #define BSL17(m) BSL16(m) LE(m(17))
176 #define BSL18(m) BSL17(m) LE(m(18))
177 #define BSL19(m) BSL18(m) LE(m(19))
178
179 // a macro generating a blank-separated list in reverse order
180 //
181 // usage: pass the name of a macro taking a number argument, e.g.
182 // #define MY_MACRO(n) a##n
183 // RBSL0(MY_MACRO) -->
184 // RBSL1(MY_MACRO) --> a1
185 // RBSL2(MY_MACRO) --> a2 a1
186 #define RBSL0(m)
187 #define RBSL1(m) LE(m(1))
188 #define RBSL2(m) LE(m(2)) RBSL1(m)
189 #define RBSL3(m) LE(m(3)) RBSL2(m)
190 #define RBSL4(m) LE(m(4)) RBSL3(m)
191 #define RBSL5(m) LE(m(5)) RBSL4(m)
192 #define RBSL6(m) LE(m(6)) RBSL5(m)
193 #define RBSL7(m) LE(m(7)) RBSL6(m)
194 #define RBSL8(m) LE(m(8)) RBSL7(m)
195 #define RBSL9(m) LE(m(9)) RBSL8(m)
196 #define RBSL10(m) LE(m(10)) RBSL9(m)
197 #define RBSL11(m) LE(m(11)) RBSL10(m)
198 #define RBSL12(m) LE(m(12)) RBSL11(m)
199 #define RBSL13(m) LE(m(13)) RBSL12(m)
200 #define RBSL14(m) LE(m(14)) RBSL13(m)
201 #define RBSL15(m) LE(m(15)) RBSL14(m)
202 #define RBSL16(m) LE(m(16)) RBSL15(m)
203 #define RBSL17(m) LE(m(17)) RBSL16(m)
204 #define RBSL18(m) LE(m(18)) RBSL17(m)
205 #define RBSL19(m) LE(m(19)) RBSL18(m)
206
207 // a macro generating a comma-separated list
208 //
209 // usage: pass the name of a macro taking a number argument, e.g.
210 // #define MY_MACRO(n) a##n
211 // CSL0(MY_MACRO) -->
212 // CSL1(MY_MACRO) --> a1
213 // CSL2(MY_MACRO) --> a1, a2
214 #define CSL0(m)
215 #define CSL1(m) LE(m(1))
216 #define CSL2(m) CSL1(m), LE(m(2))
217 #define CSL3(m) CSL2(m), LE(m(3))
218 #define CSL4(m) CSL3(m), LE(m(4))
219 #define CSL5(m) CSL4(m), LE(m(5))
220 #define CSL6(m) CSL5(m), LE(m(6))
221 #define CSL7(m) CSL6(m), LE(m(7))
222 #define CSL8(m) CSL7(m), LE(m(8))
223 #define CSL9(m) CSL8(m), LE(m(9))
224 #define CSL10(m) CSL9(m), LE(m(10))
225 #define CSL11(m) CSL10(m), LE(m(11))
226 #define CSL12(m) CSL11(m), LE(m(12))
227 #define CSL13(m) CSL12(m), LE(m(13))
228 #define CSL14(m) CSL13(m), LE(m(14))
229 #define CSL15(m) CSL14(m), LE(m(15))
230 #define CSL16(m) CSL15(m), LE(m(16))
231 #define CSL17(m) CSL16(m), LE(m(17))
232 #define CSL18(m) CSL17(m), LE(m(18))
233 #define CSL19(m) CSL18(m), LE(m(19))
234
235 // a macro generating a comma-preceded list
236 //
237 // usage: pass the name of a macro taking a number argument, e.g.
238 // #define MY_MACRO(n) a##n
239 // CPL0(MY_MACRO) -->
240 // CPL1(MY_MACRO) --> ,a1
241 // CPL2(MY_MACRO) --> ,a1 ,a2
242 #define CPL0(m)
243 #define CPL1(m) ,LE(m(1))
244 #define CPL2(m) CPL1(m) ,LE(m(2))
245 #define CPL3(m) CPL2(m) ,LE(m(3))
246 #define CPL4(m) CPL3(m) ,LE(m(4))
247 #define CPL5(m) CPL4(m) ,LE(m(5))
248 #define CPL6(m) CPL5(m) ,LE(m(6))
249 #define CPL7(m) CPL6(m) ,LE(m(7))
250 #define CPL8(m) CPL7(m) ,LE(m(8))
251 #define CPL9(m) CPL8(m) ,LE(m(9))
252 #define CPL10(m) CPL9(m) ,LE(m(10))
253 #define CPL11(m) CPL10(m) ,LE(m(11))
254 #define CPL12(m) CPL11(m) ,LE(m(12))
255 #define CPL13(m) CPL12(m) ,LE(m(13))
256 #define CPL14(m) CPL13(m) ,LE(m(14))
257 #define CPL15(m) CPL14(m) ,LE(m(15))
258 #define CPL16(m) CPL15(m) ,LE(m(16))
259 #define CPL17(m) CPL16(m) ,LE(m(17))
260 #define CPL18(m) CPL17(m) ,LE(m(18))
261 #define CPL19(m) CPL18(m) ,LE(m(19))
262
263 // a macro generating a comma-terminated list
264 //
265 // usage: pass the name of a macro taking a number argument, e.g.
266 // #define MY_MACRO(n) a##n
267 // CTL0(MY_MACRO) -->
268 // CTL1(MY_MACRO) --> a1,
269 // CTL2(MY_MACRO) --> a1, a2,
270 #define CTL0(m)
271 #define CTL1(m) LE(m(1)),
272 #define CTL2(m) CTL1(m) LE(m(2)),
273 #define CTL3(m) CTL2(m) LE(m(3)),
274 #define CTL4(m) CTL3(m) LE(m(4)),
275 #define CTL5(m) CTL4(m) LE(m(5)),
276 #define CTL6(m) CTL5(m) LE(m(6)),
277 #define CTL7(m) CTL6(m) LE(m(7)),
278 #define CTL8(m) CTL7(m) LE(m(8)),
279 #define CTL9(m) CTL8(m) LE(m(9)),
280 #define CTL10(m) CTL9(m) LE(m(10)),
281 #define CTL11(m) CTL10(m) LE(m(11)),
282 #define CTL12(m) CTL11(m) LE(m(12)),
283 #define CTL13(m) CTL12(m) LE(m(13)),
284 #define CTL14(m) CTL13(m) LE(m(14)),
285 #define CTL15(m) CTL14(m) LE(m(15)),
286 #define CTL16(m) CTL15(m) LE(m(16)),
287 #define CTL17(m) CTL16(m) LE(m(17)),
288 #define CTL18(m) CTL17(m) LE(m(18)),
289 #define CTL19(m) CTL18(m) LE(m(19)),
290
291 // ---------------------------------------------------------------------------
292 // Stringification Macros
293 // ---------------------------------------------------------------------------
294
295 // macro to stringify arguments, which are not expanded, e.g.
296 // #define A B
297 // STRING_NE(A) --> "A"
298 #define STRING_NE(x) #x
299
300 // 2nd level macro to stringify arguments, which are expanded, e.g.
301 // #define A B
302 // STRING(A) --> "B"
303 #define STRING(m) STRING_NE(m)
304
305 // Issues with generating stringified lists:
306 //
307 // The argument to STRING cannot contain commas, e.g.
308 // #define CSL a1, a2
309 // STRING(CSL) --> error: macro "STRING" passed 2 arguments...
310 //
311 // Grouping the arguments with (), makes them part of the string, e.g.
312 // #define STRINGP(x) STRING( (x) )
313 // STRINGP(CSL) --> "(a1, a2)"
314 //
315 // Workaround: stringify the elements individually, which are then
316 // concatenated into one string by the compiler, e.g., generate
317 // "a1" ", " "a2"
318
319 // macro generating a comma-separated, stringified list
320 //
321 // usage: pass the name of a macro taking a number argument, e.g.
322 // #define MY_MACRO(n) a##n
323 // SCSL0(MY_MACRO) -->
324 // SCSL1(MY_MACRO) --> "a1"
325 // SCSL2(MY_MACRO) --> "a1" ", " "a2"
326 // ...
327 #define SCSL0(m)
328 #define SCSL1(m) STRING(m(1))
329 #define SCSL2(m) SCSL1(m) ", " STRING(m(2))
330 #define SCSL3(m) SCSL2(m) ", " STRING(m(3))
331 #define SCSL4(m) SCSL3(m) ", " STRING(m(4))
332 #define SCSL5(m) SCSL4(m) ", " STRING(m(5))
333 #define SCSL6(m) SCSL5(m) ", " STRING(m(6))
334 #define SCSL7(m) SCSL6(m) ", " STRING(m(7))
335 #define SCSL8(m) SCSL7(m) ", " STRING(m(8))
336 #define SCSL9(m) SCSL8(m) ", " STRING(m(9))
337 #define SCSL10(m) SCSL9(m) ", " STRING(m(10))
338 #define SCSL11(m) SCSL10(m) ", " STRING(m(11))
339 #define SCSL12(m) SCSL11(m) ", " STRING(m(12))
340 #define SCSL13(m) SCSL12(m) ", " STRING(m(13))
341 #define SCSL14(m) SCSL13(m) ", " STRING(m(14))
342 #define SCSL15(m) SCSL14(m) ", " STRING(m(15))
343 #define SCSL16(m) SCSL15(m) ", " STRING(m(16))
344 #define SCSL17(m) SCSL16(m) ", " STRING(m(17))
345 #define SCSL18(m) SCSL17(m) ", " STRING(m(18))
346 #define SCSL19(m) SCSL18(m) ", " STRING(m(19))
347
348 // macro generating a comma-preceded, stringified list
349 //
350 // usage: pass the name of a macro taking a number argument, e.g.
351 // #define MY_MACRO(n) a##n
352 // SCPL0(MY_MACRO) -->
353 // SCPL1(MY_MACRO) --> ", " "a1"
354 // SCPL2(MY_MACRO) --> ", " "a1" ", " "a2"
355 // ...
356 #define SCPL0(m)
357 #define SCPL1(m) ", " STRING(m(1))
358 #define SCPL2(m) SCPL1(m) ", " STRING(m(2))
359 #define SCPL3(m) SCPL2(m) ", " STRING(m(3))
360 #define SCPL4(m) SCPL3(m) ", " STRING(m(4))
361 #define SCPL5(m) SCPL4(m) ", " STRING(m(5))
362 #define SCPL6(m) SCPL5(m) ", " STRING(m(6))
363 #define SCPL7(m) SCPL6(m) ", " STRING(m(7))
364 #define SCPL8(m) SCPL7(m) ", " STRING(m(8))
365 #define SCPL9(m) SCPL8(m) ", " STRING(m(9))
366 #define SCPL10(m) SCPL9(m) ", " STRING(m(10))
367 #define SCPL11(m) SCPL10(m) ", " STRING(m(11))
368 #define SCPL12(m) SCPL11(m) ", " STRING(m(12))
369 #define SCPL13(m) SCPL12(m) ", " STRING(m(13))
370 #define SCPL14(m) SCPL13(m) ", " STRING(m(14))
371 #define SCPL15(m) SCPL14(m) ", " STRING(m(15))
372 #define SCPL16(m) SCPL15(m) ", " STRING(m(16))
373 #define SCPL17(m) SCPL16(m) ", " STRING(m(17))
374 #define SCPL18(m) SCPL17(m) ", " STRING(m(18))
375 #define SCPL19(m) SCPL18(m) ", " STRING(m(19))
376
377 // ---------------------------------------------------------------------------
378 // Name Definitions used in Wrapper Function Templates
379 // ---------------------------------------------------------------------------
380
381 // JNI environment parameter declaration
382 #define JEPD JNIEnv * env
383
384 // Stringified JNI environment type
385 #define SJET "JNIEnv *"
386
387 // ---------------------------------------------------------------------------
388
389 // JNI Java class parameter declaration
390 #define JCPD jclass cls
391
392 // Stringified JNI Java class type
393 #define SJCT "jclass"
394
395 // ---------------------------------------------------------------------------
396
397 // Template formal result type declaration
398 #define TFRTD typename RT
399
400 // C formal result type
401 #define CFRT typename RT::CF_t
402
403 // Java formal result type
404 #define JFRT typename RT::JF_t
405
406 // Java actual result type
407 #define JART typename RT::JA_t
408
409 // C actual result type
410 #define CART typename RT::CA_t
411
412 // Stringified Java formal result type
413 #define SJFRT "RT::JF_t"
414
415 // C actual result declaration
416 #define CARD CART car
417
418 // Java actual result declaration
419 #define JARD JART jar = 0
420
421 // ---------------------------------------------------------------------------
422
423 // Template formal object type declaration
424 #define TFOT typename OT
425
426 // Short C formal object type (not preceded by 'typename')
427 #define SCFOT OT::CF_t
428
429 // Java actual object type
430 #define JAOT typename OT::JA_t
431
432 // C actual object type
433 #define CAOT typename OT::CA_t
434
435 // Java formal object parameter declaration
436 #define JFOPD typename OT::JF_t jfo
437
438 // Stringified Java formal object type
439 #define SJFOT "OT::JF_t"
440
441 // ---------------------------------------------------------------------------
442
443 // Template formal parameter type
444 #define TFPT(n) P##n##T
445
446 // Template formal parameter type declaration
447 #define TFPTD(n) typename P##n##T
448
449 // C formal parameter type
450 #define CFPT(n) typename P##n##T::CF_t
451
452 // Java formal parameter type
453 #define JFPT(n) typename P##n##T::JF_t
454
455 // Java actual parameter type
456 #define JAPT(n) typename P##n##T::JA_t
457
458 // C actual parameter type
459 #define CAPT(n) typename P##n##T::CA_t
460
461 // Java formal parameter declaration
462 #define JFPD(n) JFPT(n) jfp##n
463
464 // Java formal parameter
465 #define JFP(n) jfp##n
466
467 // C actual parameter
468 #define CAP(n) cap##n
469
470 // Short Java formal parameter type
471 #define SJFPT(n) P##n##T::JF_t
472
473 // ---------------------------------------------------------------------------
474
475 // status flag declaration
476 #define SFD int s = 1; (void)s;
477
478 #define PARAM_CONV_BEGIN(n) \
479 JAPT(n) jap##n = cast< JAPT(n), JFPT(n) >(jfp##n); \
480 CAPT(n) cap##n = Param< JAPT(n), CAPT(n) >::convert(s, jap##n, env); \
481 if (s == 0) {
482
483 #define PARAM_CONV_END(n) \
484 Param< JAPT(n), CAPT(n) >::release(cap##n, jap##n, env); \
485 }
486
487 #define TARGET_CONV_BEGIN \
488 JAOT jao = cast< JAOT, TFOT::JF_t >(jfo); \
489 CAOT & cao = Target< JAOT, CAOT >::convert(s, jao, env); \
490 if (s == 0) {
491
492 #define TARGET_CONV_END \
493 Target< JAOT, CAOT >::release(cao, jao, env); \
494 }
495
496 #define RESULT_CONV \
497 jar = Result< JART, CART >::convert(car, env);
498
499 #define RESULT_CAST \
500 cast< JFRT, JART >(jar);
501
502 // ---------------------------------------------------------------------------
503 // Data Member Access
504 // ---------------------------------------------------------------------------
505
506 // non-member field or static field read access
507 template< TFRTD,
508 CFRT & D >
509 inline
510 JFRT
gget(JEPD,JCPD)511 gget(JEPD, JCPD)
512 {
513 TRACE(SJFRT " gget(" SJET ", " SJCT ")");
514 (void)cls;
515 JARD;
516 CARD = D;
517 RESULT_CONV;
518 return RESULT_CAST;
519 }
520
521 // member field read access
522 template< TFOT,
523 TFRTD,
524 CFRT SCFOT::*D >
525 inline JFRT
gget(JEPD,JFOPD)526 gget(JEPD, JFOPD)
527 {
528 TRACE(SJFRT " gget(" SJET ", " SJFOT ")");
529 JARD;
530 SFD;
531 TARGET_CONV_BEGIN;
532 CARD = (cao).*D;
533 RESULT_CONV;
534 TARGET_CONV_END;
535 return RESULT_CAST;
536 }
537
538 // non-member field or static field write access
539 template< TFPTD(1),
540 CFPT(1) & D >
541 inline
542 void
543 gset(JEPD, JCPD, JFPD(1))
544 {
545 TRACE("void" " gset(" SJET ", " SJCT ", " STRING(SJFPT(1)) ")");
546 (void)cls;
547 SFD;
548 PARAM_CONV_BEGIN(1);
549 D = CAP(1);
550 PARAM_CONV_END(1);
551 }
552
553 // member field write access
554 template< TFOT,
555 TFPTD(1),
556 CFPT(1) SCFOT::*D >
557 inline void
gset(JEPD,JFOPD CPL1 (JFPD))558 gset(JEPD, JFOPD CPL1(JFPD))
559 {
560 TRACE("void" " gset(" SJET ", " SJFOT ", " STRING(SJFPT(1)) ")");
561 SFD;
562 TARGET_CONV_BEGIN;
563 PARAM_CONV_BEGIN(1);
564 (cao).*D = CAP(1);
565 PARAM_CONV_END(1);
566 TARGET_CONV_END;
567 }
568
569 // ---------------------------------------------------------------------------
570 // Non-Member and Static Member Function Calls, No-Return
571 // ---------------------------------------------------------------------------
572
573 // parameters: n = n-ary function
574 #define TFD_F(n) \
575 template< CTL##n(TFPTD) \
576 void F(CSL##n(CFPT)) > \
577 inline void \
578 gcall_fv(JEPD, JCPD CPL##n(JFPD)) \
579 { \
580 TRACE("void" " gcall_fv(" SJET ", " SJCT SCPL##n(SJFPT) ")"); \
581 (void)env; (void)cls; \
582 SFD; \
583 BSL##n(PARAM_CONV_BEGIN); \
584 F( CSL##n(CAP) ); \
585 RBSL##n(PARAM_CONV_END); \
586 }
587
588 // generate the function templates (separate lines for proper error messages)
589 TFD_F(0)
590 TFD_F(1)
591 TFD_F(2)
592 TFD_F(3)
593 TFD_F(4)
594 TFD_F(5)
595 TFD_F(6)
596 TFD_F(7)
597 TFD_F(8)
598 TFD_F(9)
599 TFD_F(10)
600 TFD_F(11)
601 TFD_F(12)
602 TFD_F(13)
603 TFD_F(14)
604 TFD_F(15)
605 TFD_F(16)
606 TFD_F(17)
607 TFD_F(18)
608 TFD_F(19)
609
610 // ---------------------------------------------------------------------------
611 // Non-Member and Static Member Function Calls, Return
612 // ---------------------------------------------------------------------------
613
614 // parameters: n = n-ary function
615 #define TFD_FR(n) \
616 template< TFRTD, \
617 CTL##n(TFPTD) \
618 CFRT F(CSL##n(CFPT)) > \
619 inline JFRT \
620 gcall_fr(JEPD, JCPD CPL##n(JFPD)) \
621 { \
622 TRACE(SJFRT " gcall_fr(" SJET ", " SJCT SCPL##n(SJFPT) ")"); \
623 (void)cls; \
624 JARD; \
625 SFD; \
626 BSL##n(PARAM_CONV_BEGIN); \
627 CARD = F( CSL##n(CAP) ); \
628 RESULT_CONV; \
629 RBSL##n(PARAM_CONV_END); \
630 return RESULT_CAST; \
631 }
632
633 // generate the function templates (separate lines help error messages)
634 TFD_FR(0)
635 TFD_FR(1)
636 TFD_FR(2)
637 TFD_FR(3)
638 TFD_FR(4)
639 TFD_FR(5)
640 TFD_FR(6)
641 TFD_FR(7)
642 TFD_FR(8)
643 TFD_FR(9)
644 TFD_FR(10)
645 TFD_FR(11)
646 TFD_FR(12)
647 TFD_FR(13)
648 TFD_FR(14)
649 TFD_FR(15)
650 TFD_FR(16)
651 TFD_FR(17)
652 TFD_FR(18)
653 TFD_FR(19)
654
655 // ---------------------------------------------------------------------------
656 // Non-Static Const/Non-Const Member Function Calls, No-Return
657 // ---------------------------------------------------------------------------
658
659 // parameters: n = n-ary function
660 //
661 // we do not generate a separate set of templates for const members anymore:
662 // cm = empty or 'const'
663 // #define TFD_MF(n,cm)
664 // ... void (SCFOT::*F)(CSL##n(CFPT)) cm >
665 // for
666 // - leads to template ambiguities with const member function ptr type
667 // - empty macro arguments are undefined in ISO C90 and ISO C++98
668 //
669 #define TFD_MF(n) \
670 template< TFOT, \
671 CTL##n(TFPTD) \
672 void (SCFOT::*F)(CSL##n(CFPT)) > \
673 inline void \
674 gcall_mfv(JEPD, JFOPD CPL##n(JFPD)) \
675 { \
676 TRACE("void" " gcall_mfv(" SJET ", " SJFOT SCPL##n(SJFPT) ")"); \
677 SFD; \
678 TARGET_CONV_BEGIN; \
679 BSL##n(PARAM_CONV_BEGIN); \
680 ((cao).*F)( CSL##n(CAP) ); \
681 RBSL##n(PARAM_CONV_END); \
682 TARGET_CONV_END; \
683 }
684
685 // generate the function templates (separate lines help error messages)
686 TFD_MF(0)
687 TFD_MF(1)
688 TFD_MF(2)
689 TFD_MF(3)
690 TFD_MF(4)
691 TFD_MF(5)
692 TFD_MF(6)
693 TFD_MF(7)
694 TFD_MF(8)
695 TFD_MF(9)
696 TFD_MF(10)
697 TFD_MF(11)
698 TFD_MF(12)
699 TFD_MF(13)
700 TFD_MF(14)
701 TFD_MF(15)
702 TFD_MF(16)
703 TFD_MF(17)
704 TFD_MF(18)
705 TFD_MF(19)
706
707 // ---------------------------------------------------------------------------
708 // Non-Static Const/Non-Const Member Function Calls, Return
709 // ---------------------------------------------------------------------------
710
711 // parameters: n = n-ary, cm = const member function qualifier
712 //
713 // we do not generate a separate set of templates for const members anymore:
714 // cm = empty or 'const'
715 // #define TFD_MFR(n,cm)
716 // ... CFRT (SCFOT::*F)(CSL##n(CFPT)) cm >
717 // for
718 // - leads to template ambiguities with const member function ptr type
719 // - empty macro arguments are undefined in ISO C90 and ISO C++98
720 //
721 #define TFD_MFR(n) \
722 template< TFOT, \
723 TFRTD, \
724 CTL##n(TFPTD) \
725 CFRT (SCFOT::*F)(CSL##n(CFPT)) > \
726 inline JFRT \
727 gcall_mfr(JEPD, JFOPD CPL##n(JFPD)) \
728 { \
729 TRACE(SJFRT " gcall_mfr(" SJET ", " SJFOT SCPL##n(SJFPT) ")"); \
730 JARD; \
731 SFD; \
732 TARGET_CONV_BEGIN; \
733 BSL##n(PARAM_CONV_BEGIN); \
734 CARD = ((cao).*F)( CSL##n(CAP) ); \
735 RESULT_CONV; \
736 RBSL##n(PARAM_CONV_END); \
737 TARGET_CONV_END; \
738 return RESULT_CAST; \
739 }
740
741 // generate the function templates (separate lines help error messages)
742 TFD_MFR(0)
743 TFD_MFR(1)
744 TFD_MFR(2)
745 TFD_MFR(3)
746 TFD_MFR(4)
747 TFD_MFR(5)
748 TFD_MFR(6)
749 TFD_MFR(7)
750 TFD_MFR(8)
751 TFD_MFR(9)
752 TFD_MFR(10)
753 TFD_MFR(11)
754 TFD_MFR(12)
755 TFD_MFR(13)
756 TFD_MFR(14)
757 TFD_MFR(15)
758 TFD_MFR(16)
759 TFD_MFR(17)
760 TFD_MFR(18)
761 TFD_MFR(19)
762
763 // ---------------------------------------------------------------------------
764 // Internal C++ Constructor/Destructor/Index Access Wrappers
765 // ---------------------------------------------------------------------------
766
767 // parameters: n = n-ary
768
769 // class template calling the array destructor
770 template< typename C > struct ArrayHelper;
771
772 template< typename C >
773 struct ArrayHelper< C * > {
774 static void
cdeleteArrayHelper775 cdelete(C * p0) {
776 TRACE("void ArrayHelper::cdelete(C *)");
777 delete[] p0;
778 }
779
780 static C *
ccreateArrayHelper781 ccreate(int32_t p0) {
782 TRACE("C * ArrayHelper::ccreate(int32_t)");
783 // ISO C++: 'new' throws std::bad_alloc if unsuccessful
784 return new C[p0];
785 }
786
787 static C *
catArrayHelper788 cat(C * p0, int32_t i) {
789 TRACE("C * ArrayHelper::cat(C *)");
790 return (p0 + i);
791 }
792 };
793
794 template< typename C >
795 struct ArrayHelper< C & > {
796 static void
cdeleteArrayHelper797 cdelete(C & p0) {
798 TRACE("void ArrayHelper::cdelete(C &)");
799 ArrayHelper< C * >::cdelete(&p0);
800 }
801
802 static C &
ccreateArrayHelper803 ccreate(int32_t p0) {
804 TRACE("C & ArrayHelper::ccreate(int32_t)");
805 return *ArrayHelper< C * >::ccreate(p0);
806 }
807
808 static C &
catArrayHelper809 cat(C & p0, int32_t i) {
810 TRACE("C & ArrayHelper::cat(C &)");
811 return *ArrayHelper< C * >::cat(&p0, i);
812 }
813 };
814
815 // ---------------------------------------------------------------------------
816
817 // class template calling the destructor
818 template< typename C > struct Destructor;
819
820 template< typename C >
821 struct Destructor< C * > {
822 static void
cdeleteDestructor823 cdelete(C * p0) {
824 TRACE("void Destructor::cdelete(C *)");
825 delete p0;
826 }
827 };
828
829 template< typename C >
830 struct Destructor< C & > {
831 static void
cdeleteDestructor832 cdelete(C & p0) {
833 TRACE("void Destructor::cdelete(C &)");
834 Destructor< C * >::cdelete(&p0);
835 }
836 };
837
838 // Template formal parameter type (redefine)
839 #define CC_TFPT(n) P##n##_CF_t
840
841 // Template formal parameter type declaration (redefine)
842 #define CC_TFPTD(n) typename CC_TFPT(n)
843
844 // C formal parameter type (redefine)
845 #define CC_CFPT(n) CC_TFPT(n)
846
847 // C formal parameter
848 #define CC_CFP(n) cfp##n
849
850 // C formal parameter declaration
851 #define CC_CFPD(n) CC_CFPT(n) CC_CFP(n)
852
853 // n-ary class templates calling constructors
854 #define TFD_CC(n) \
855 template< typename C CPL##n(CC_TFPTD) > struct Constructor##n; \
856 \
857 template< typename C CPL##n(CC_TFPTD) > \
858 struct Constructor##n< C * CPL##n(CC_TFPT) > { \
859 static C * \
860 ccreate(CSL##n(CC_CFPD)) { \
861 TRACE("C * ccreate(" SCSL##n(CC_TFPT) ")"); \
862 return new C(CSL##n(CC_CFP)); \
863 } \
864 }; \
865 \
866 template< typename C CPL##n(CC_TFPTD) > \
867 struct Constructor##n< C & CPL##n(CC_TFPT) > { \
868 static C & \
869 ccreate(CSL##n(CC_CFPD)) { \
870 TRACE("C & ccreate(" SCSL##n(CC_TFPT) ")"); \
871 return *Constructor##n< C * CPL##n(CC_TFPT) > \
872 ::ccreate(CSL##n(CC_CFP)); \
873 } \
874 };
875
876 // generate the class templates (separate lines help error messages)
877 TFD_CC(0)
878 TFD_CC(1)
879 TFD_CC(2)
880 TFD_CC(3)
881 TFD_CC(4)
882 TFD_CC(5)
883 TFD_CC(6)
884 TFD_CC(7)
885 TFD_CC(8)
886 TFD_CC(9)
887 TFD_CC(10)
888 TFD_CC(11)
889 TFD_CC(12)
890 TFD_CC(13)
891 TFD_CC(14)
892 TFD_CC(15)
893 TFD_CC(16)
894 TFD_CC(17)
895 TFD_CC(18)
896 TFD_CC(19)
897
898 // ---------------------------------------------------------------------------
899 // Constructor, Destructor, and Index Access Calls
900 // ---------------------------------------------------------------------------
901
902 // array delete template function definition
903 template< TFPTD(1) >
904 inline
905 void
906 gdeleteArray(JEPD, JCPD, JFPD(1))
907 {
908 TRACE("void gdeleteArray(" SJET ", " SJCT ", " STRING(SJFPT(1)) ")");
909 (void)cls;
910 // not using gcall_fv<...>(...) due to call to detachWrapper()
911 SFD;
912 PARAM_CONV_BEGIN(1);
913 #ifdef JTIE_OBJECT_CLEAR_ADDRESS_UPON_DELETE
914 detachWrapper(jap1, env);
915 #endif // JTIE_OBJECT_CLEAR_ADDRESS_UPON_DELETE
916 ArrayHelper< CFPT(1) >::cdelete(CAP(1));
917 PARAM_CONV_END(1);
918 }
919
920 // array create template function definition
921 template< TFRTD, TFPTD(1) >
922 inline
923 JFRT
924 gcreateArray(JEPD, JCPD, JFPD(1))
925 {
926 TRACE(SJFRT " gcreateArray(" SJET ", " SJCT ", " STRING(SJFPT(1)) ")");
927 return gcall_fr< RT, TFPT(1),
928 &ArrayHelper< CFRT >::ccreate
929 >(env, cls, JFP(1));
930 }
931
932 // array index access template function definition
933 template< TFRTD, TFPTD(1), TFPTD(2) >
934 inline
935 JFRT
936 gat(JEPD, JCPD, JFPD(1), JFPD(2))
937 {
938 TRACE(SJFRT " gat(" SJET ", " SJCT ", " STRING(SJFPT(1)) ", " STRING(SJFPT(2)) ")");
939 return gcall_fr< RT, TFPT(1), TFPT(2),
940 &ArrayHelper< CFRT >::cat
941 >(env, cls, JFP(1), JFP(2));
942 }
943
944 // ---------------------------------------------------------------------------
945
946 // destructor template function definition
947 template< TFPTD(1) >
948 inline
949 void
950 gdelete(JEPD, JCPD, JFPD(1))
951 {
952 TRACE("void gdelete(" SJET ", " SJCT ", " STRING(SJFPT(1)) ")");
953 (void)cls;
954 // not using gcall_fv<...>(...) due to call to detachWrapper()
955 SFD;
956 PARAM_CONV_BEGIN(1);
957 #ifdef JTIE_OBJECT_CLEAR_ADDRESS_UPON_DELETE
958 detachWrapper(jap1, env);
959 #endif // JTIE_OBJECT_CLEAR_ADDRESS_UPON_DELETE
960 Destructor< CFPT(1) >::cdelete(CAP(1));
961 PARAM_CONV_END(1);
962 }
963
964 // n-ary constructor template function definition
965 #define TFD_C(n) \
966 template< TFRTD CPL##n(TFPTD) > \
967 inline JFRT \
968 gcreate(JEPD, JCPD CPL##n(JFPD)) \
969 { \
970 TRACE(SJFRT " gcreate(" SJET ", " SJCT SCSL##n(SJFPT) ")"); \
971 return gcall_fr< RT, CTL##n(TFPT) \
972 &Constructor##n< CFRT CPL##n(CFPT) >::ccreate \
973 >(env, cls CPL##n(JFP)); \
974 }
975
976 // generate the function templates (separate lines help error messages)
977 TFD_C(0)
978 TFD_C(1)
979 TFD_C(2)
980 TFD_C(3)
981 TFD_C(4)
982 TFD_C(5)
983 TFD_C(6)
984 TFD_C(7)
985 TFD_C(8)
986 TFD_C(9)
987 TFD_C(10)
988 TFD_C(11)
989 TFD_C(12)
990 TFD_C(13)
991 TFD_C(14)
992 TFD_C(15)
993 TFD_C(16)
994 TFD_C(17)
995 TFD_C(18)
996 TFD_C(19)
997
998 // ---------------------------------------------------------------------------
999
1000 #endif // jtie_gcalls_hpp
1001