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