]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/library/callback.c
Merge branch 'bug-623' into release/1.43.0
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / library / callback.c
1 /*******************************************************************************
2  * Copyright (c) 2000, 2012 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14  
15 /**
16  * Callback implementation.
17  */
18 #include "callback.h"
19 #include <string.h>
20
21 #ifndef CALLBACK_NATIVE
22 #define CALLBACK_NATIVE(func) Java_org_eclipse_swt_internal_Callback_##func
23 #endif
24
25 /* define this to print out debug statements */
26 /* #define DEBUG_CALL_PRINTS */
27
28 /* --------------- callback globals ----------------- */
29
30 static JavaVM *jvm = NULL;
31 static CALLBACK_DATA callbackData[MAX_CALLBACKS];
32 static int callbackEnabled = 1;
33 static int callbackEntryCount = 0;
34 static int initialized = 0;
35 static jint JNI_VERSION = 0;
36
37 #ifdef DEBUG_CALL_PRINTS
38 static int counter = 0;
39 #endif
40
41 #ifdef ATOMIC
42 #include <libkern/OSAtomic.h>
43 #define ATOMIC_INC(value) OSAtomicIncrement32(&value);
44 #define ATOMIC_DEC(value) OSAtomicDecrement32(&value);
45 #else
46 #define ATOMIC_INC(value) value++;
47 #define ATOMIC_DEC(value) value--;
48 #endif
49
50 jintLong callback(int index, ...);
51
52 #ifdef USE_ASSEMBLER
53
54 #if !(defined (_WIN32) || defined (_WIN32_WCE))
55 #include <sys/mman.h>
56 #endif
57
58 static unsigned char *callbackCode = NULL;
59 #define CALLBACK_THUNK_SIZE 64
60
61 #else
62
63 /* --------------- callback functions --------------- */
64
65
66 /* Function name from index and number of arguments */
67 #define FN(index, args) fn##index##_##args
68
69 /**
70  * Functions templates
71  *
72  * NOTE: If the maximum number of arguments changes (MAX_ARGS), the number
73  *       of function templates has to change accordingly.
74  */
75
76 /* Function template with no arguments */
77 #define FN_0(index) RETURN_TYPE FN(index, 0)() { return RETURN_CAST callback(index); }
78
79 /* Function template with 1 argument */
80 #define FN_1(index) RETURN_TYPE FN(index, 1)(jintLong p1) { return RETURN_CAST callback(index, p1); }
81
82 /* Function template with 2 arguments */
83 #define FN_2(index) RETURN_TYPE FN(index, 2)(jintLong p1, jintLong p2) { return RETURN_CAST callback(index, p1, p2); }
84
85 /* Function template with 3 arguments */
86 #define FN_3(index) RETURN_TYPE FN(index, 3)(jintLong p1, jintLong p2, jintLong p3) { return RETURN_CAST callback(index, p1, p2, p3); }
87
88 /* Function template with 4 arguments */
89 #define FN_4(index) RETURN_TYPE FN(index, 4)(jintLong p1, jintLong p2, jintLong p3, jintLong p4) { return RETURN_CAST callback(index, p1, p2, p3, p4); }
90
91 /* Function template with 5 arguments */
92 #define FN_5(index) RETURN_TYPE FN(index, 5)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5); }
93
94 /* Function template with 6 arguments */
95 #define FN_6(index) RETURN_TYPE FN(index, 6)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6); }
96
97 /* Function template with 7 arguments */
98 #define FN_7(index) RETURN_TYPE FN(index, 7)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7); }
99
100 /* Function template with 8 arguments */
101 #define FN_8(index) RETURN_TYPE FN(index, 8)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8); }
102
103 /* Function template with 9 arguments */
104 #define FN_9(index) RETURN_TYPE FN(index, 9)(jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8, jintLong p9) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
105
106 /* Function template with 10 arguments */
107 #define FN_10(index) RETURN_TYPE FN(index, 10) (jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8, jintLong p9, jintLong p10) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
108
109 /* Function template with 11 arguments */
110 #define FN_11(index) RETURN_TYPE FN(index, 11) (jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8, jintLong p9, jintLong p10, jintLong p11) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
111
112 /* Function template with 12 arguments */
113 #define FN_12(index) RETURN_TYPE FN(index, 12) (jintLong p1, jintLong p2, jintLong p3, jintLong p4, jintLong p5, jintLong p6, jintLong p7, jintLong p8, jintLong p9, jintLong p10, jintLong p11, jintLong p12) { return RETURN_CAST callback(index, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
114
115 /**
116  * Define all functions with the specified number of arguments.
117  *
118  * NOTE: If the maximum number of callbacks changes (MAX_CALLBACKS),
119  *       this macro has to be updated. 
120  */
121 #if MAX_CALLBACKS == 16
122 #define FN_BLOCK(args) \
123         FN_##args(0) \
124         FN_##args(1) \
125         FN_##args(2) \
126         FN_##args(3) \
127         FN_##args(4) \
128         FN_##args(5) \
129         FN_##args(6) \
130         FN_##args(7) \
131         FN_##args(8) \
132         FN_##args(9) \
133         FN_##args(10) \
134         FN_##args(11) \
135         FN_##args(12) \
136         FN_##args(13) \
137         FN_##args(14) \
138         FN_##args(15)
139 #elif MAX_CALLBACKS == 128
140 #define FN_BLOCK(args) \
141         FN_##args(0) \
142         FN_##args(1) \
143         FN_##args(2) \
144         FN_##args(3) \
145         FN_##args(4) \
146         FN_##args(5) \
147         FN_##args(6) \
148         FN_##args(7) \
149         FN_##args(8) \
150         FN_##args(9) \
151         FN_##args(10) \
152         FN_##args(11) \
153         FN_##args(12) \
154         FN_##args(13) \
155         FN_##args(14) \
156         FN_##args(15) \
157         FN_##args(16) \
158         FN_##args(17) \
159         FN_##args(18) \
160         FN_##args(19) \
161         FN_##args(20) \
162         FN_##args(21) \
163         FN_##args(22) \
164         FN_##args(23) \
165         FN_##args(24) \
166         FN_##args(25) \
167         FN_##args(26) \
168         FN_##args(27) \
169         FN_##args(28) \
170         FN_##args(29) \
171         FN_##args(30) \
172         FN_##args(31) \
173         FN_##args(32) \
174         FN_##args(33) \
175         FN_##args(34) \
176         FN_##args(35) \
177         FN_##args(36) \
178         FN_##args(37) \
179         FN_##args(38) \
180         FN_##args(39) \
181         FN_##args(40) \
182         FN_##args(41) \
183         FN_##args(42) \
184         FN_##args(43) \
185         FN_##args(44) \
186         FN_##args(45) \
187         FN_##args(46) \
188         FN_##args(47) \
189         FN_##args(48) \
190         FN_##args(49) \
191         FN_##args(50) \
192         FN_##args(51) \
193         FN_##args(52) \
194         FN_##args(53) \
195         FN_##args(54) \
196         FN_##args(55) \
197         FN_##args(56) \
198         FN_##args(57) \
199         FN_##args(58) \
200         FN_##args(59) \
201         FN_##args(60) \
202         FN_##args(61) \
203         FN_##args(62) \
204         FN_##args(63) \
205         FN_##args(64) \
206         FN_##args(65) \
207         FN_##args(66) \
208         FN_##args(67) \
209         FN_##args(68) \
210         FN_##args(69) \
211         FN_##args(70) \
212         FN_##args(71) \
213         FN_##args(72) \
214         FN_##args(73) \
215         FN_##args(74) \
216         FN_##args(75) \
217         FN_##args(76) \
218         FN_##args(77) \
219         FN_##args(78) \
220         FN_##args(79) \
221         FN_##args(80) \
222         FN_##args(81) \
223         FN_##args(82) \
224         FN_##args(83) \
225         FN_##args(84) \
226         FN_##args(85) \
227         FN_##args(86) \
228         FN_##args(87) \
229         FN_##args(88) \
230         FN_##args(89) \
231         FN_##args(90) \
232         FN_##args(91) \
233         FN_##args(92) \
234         FN_##args(93) \
235         FN_##args(94) \
236         FN_##args(95) \
237         FN_##args(96) \
238         FN_##args(97) \
239         FN_##args(98) \
240         FN_##args(99) \
241         FN_##args(100) \
242         FN_##args(101) \
243         FN_##args(102) \
244         FN_##args(103) \
245         FN_##args(104) \
246         FN_##args(105) \
247         FN_##args(106) \
248         FN_##args(107) \
249         FN_##args(108) \
250         FN_##args(109) \
251         FN_##args(110) \
252         FN_##args(111) \
253         FN_##args(112) \
254         FN_##args(113) \
255         FN_##args(114) \
256         FN_##args(115) \
257         FN_##args(116) \
258         FN_##args(117) \
259         FN_##args(118) \
260         FN_##args(119) \
261         FN_##args(120) \
262         FN_##args(121) \
263         FN_##args(122) \
264         FN_##args(123) \
265         FN_##args(124) \
266         FN_##args(125) \
267         FN_##args(126) \
268         FN_##args(127)
269 #elif MAX_CALLBACKS == 256
270 #define FN_BLOCK(args) \
271         FN_##args(0) \
272         FN_##args(1) \
273         FN_##args(2) \
274         FN_##args(3) \
275         FN_##args(4) \
276         FN_##args(5) \
277         FN_##args(6) \
278         FN_##args(7) \
279         FN_##args(8) \
280         FN_##args(9) \
281         FN_##args(10) \
282         FN_##args(11) \
283         FN_##args(12) \
284         FN_##args(13) \
285         FN_##args(14) \
286         FN_##args(15) \
287         FN_##args(16) \
288         FN_##args(17) \
289         FN_##args(18) \
290         FN_##args(19) \
291         FN_##args(20) \
292         FN_##args(21) \
293         FN_##args(22) \
294         FN_##args(23) \
295         FN_##args(24) \
296         FN_##args(25) \
297         FN_##args(26) \
298         FN_##args(27) \
299         FN_##args(28) \
300         FN_##args(29) \
301         FN_##args(30) \
302         FN_##args(31) \
303         FN_##args(32) \
304         FN_##args(33) \
305         FN_##args(34) \
306         FN_##args(35) \
307         FN_##args(36) \
308         FN_##args(37) \
309         FN_##args(38) \
310         FN_##args(39) \
311         FN_##args(40) \
312         FN_##args(41) \
313         FN_##args(42) \
314         FN_##args(43) \
315         FN_##args(44) \
316         FN_##args(45) \
317         FN_##args(46) \
318         FN_##args(47) \
319         FN_##args(48) \
320         FN_##args(49) \
321         FN_##args(50) \
322         FN_##args(51) \
323         FN_##args(52) \
324         FN_##args(53) \
325         FN_##args(54) \
326         FN_##args(55) \
327         FN_##args(56) \
328         FN_##args(57) \
329         FN_##args(58) \
330         FN_##args(59) \
331         FN_##args(60) \
332         FN_##args(61) \
333         FN_##args(62) \
334         FN_##args(63) \
335         FN_##args(64) \
336         FN_##args(65) \
337         FN_##args(66) \
338         FN_##args(67) \
339         FN_##args(68) \
340         FN_##args(69) \
341         FN_##args(70) \
342         FN_##args(71) \
343         FN_##args(72) \
344         FN_##args(73) \
345         FN_##args(74) \
346         FN_##args(75) \
347         FN_##args(76) \
348         FN_##args(77) \
349         FN_##args(78) \
350         FN_##args(79) \
351         FN_##args(80) \
352         FN_##args(81) \
353         FN_##args(82) \
354         FN_##args(83) \
355         FN_##args(84) \
356         FN_##args(85) \
357         FN_##args(86) \
358         FN_##args(87) \
359         FN_##args(88) \
360         FN_##args(89) \
361         FN_##args(90) \
362         FN_##args(91) \
363         FN_##args(92) \
364         FN_##args(93) \
365         FN_##args(94) \
366         FN_##args(95) \
367         FN_##args(96) \
368         FN_##args(97) \
369         FN_##args(98) \
370         FN_##args(99) \
371         FN_##args(100) \
372         FN_##args(101) \
373         FN_##args(102) \
374         FN_##args(103) \
375         FN_##args(104) \
376         FN_##args(105) \
377         FN_##args(106) \
378         FN_##args(107) \
379         FN_##args(108) \
380         FN_##args(109) \
381         FN_##args(110) \
382         FN_##args(111) \
383         FN_##args(112) \
384         FN_##args(113) \
385         FN_##args(114) \
386         FN_##args(115) \
387         FN_##args(116) \
388         FN_##args(117) \
389         FN_##args(118) \
390         FN_##args(119) \
391         FN_##args(120) \
392         FN_##args(121) \
393         FN_##args(122) \
394         FN_##args(123) \
395         FN_##args(124) \
396         FN_##args(125) \
397         FN_##args(126) \
398         FN_##args(127) \
399         FN_##args(128) \
400         FN_##args(129) \
401         FN_##args(130) \
402         FN_##args(131) \
403         FN_##args(132) \
404         FN_##args(133) \
405         FN_##args(134) \
406         FN_##args(135) \
407         FN_##args(136) \
408         FN_##args(137) \
409         FN_##args(138) \
410         FN_##args(139) \
411         FN_##args(140) \
412         FN_##args(141) \
413         FN_##args(142) \
414         FN_##args(143) \
415         FN_##args(144) \
416         FN_##args(145) \
417         FN_##args(146) \
418         FN_##args(147) \
419         FN_##args(148) \
420         FN_##args(149) \
421         FN_##args(150) \
422         FN_##args(151) \
423         FN_##args(152) \
424         FN_##args(153) \
425         FN_##args(154) \
426         FN_##args(155) \
427         FN_##args(156) \
428         FN_##args(157) \
429         FN_##args(158) \
430         FN_##args(159) \
431         FN_##args(160) \
432         FN_##args(161) \
433         FN_##args(162) \
434         FN_##args(163) \
435         FN_##args(164) \
436         FN_##args(165) \
437         FN_##args(166) \
438         FN_##args(167) \
439         FN_##args(168) \
440         FN_##args(169) \
441         FN_##args(170) \
442         FN_##args(171) \
443         FN_##args(172) \
444         FN_##args(173) \
445         FN_##args(174) \
446         FN_##args(175) \
447         FN_##args(176) \
448         FN_##args(177) \
449         FN_##args(178) \
450         FN_##args(179) \
451         FN_##args(180) \
452         FN_##args(181) \
453         FN_##args(182) \
454         FN_##args(183) \
455         FN_##args(184) \
456         FN_##args(185) \
457         FN_##args(186) \
458         FN_##args(187) \
459         FN_##args(188) \
460         FN_##args(189) \
461         FN_##args(190) \
462         FN_##args(191) \
463         FN_##args(192) \
464         FN_##args(193) \
465         FN_##args(194) \
466         FN_##args(195) \
467         FN_##args(196) \
468         FN_##args(197) \
469         FN_##args(198) \
470         FN_##args(199) \
471         FN_##args(200) \
472         FN_##args(201) \
473         FN_##args(202) \
474         FN_##args(203) \
475         FN_##args(204) \
476         FN_##args(205) \
477         FN_##args(206) \
478         FN_##args(207) \
479         FN_##args(208) \
480         FN_##args(209) \
481         FN_##args(210) \
482         FN_##args(211) \
483         FN_##args(212) \
484         FN_##args(213) \
485         FN_##args(214) \
486         FN_##args(215) \
487         FN_##args(216) \
488         FN_##args(217) \
489         FN_##args(218) \
490         FN_##args(219) \
491         FN_##args(220) \
492         FN_##args(221) \
493         FN_##args(222) \
494         FN_##args(223) \
495         FN_##args(224) \
496         FN_##args(225) \
497         FN_##args(226) \
498         FN_##args(227) \
499         FN_##args(228) \
500         FN_##args(229) \
501         FN_##args(230) \
502         FN_##args(231) \
503         FN_##args(232) \
504         FN_##args(233) \
505         FN_##args(234) \
506         FN_##args(235) \
507         FN_##args(236) \
508         FN_##args(237) \
509         FN_##args(238) \
510         FN_##args(239) \
511         FN_##args(240) \
512         FN_##args(241) \
513         FN_##args(242) \
514         FN_##args(243) \
515         FN_##args(244) \
516         FN_##args(245) \
517         FN_##args(246) \
518         FN_##args(247) \
519         FN_##args(248) \
520         FN_##args(249) \
521         FN_##args(250) \
522         FN_##args(251) \
523         FN_##args(252) \
524         FN_##args(253) \
525         FN_##args(254) \
526         FN_##args(255)
527 #else
528 #error Invalid MAX_CALLBACKS
529 #endif /* MAX_CALLBACKS == 16 */
530
531 /**
532  * Define all callback functions.
533  *
534  * NOTE: If the maximum number of arguments changes (MAX_ARGS), the following
535  *       has to change accordinglly.
536  */
537 FN_BLOCK(0)
538 FN_BLOCK(1)
539 FN_BLOCK(2)
540 FN_BLOCK(3)
541 FN_BLOCK(4)
542 FN_BLOCK(5)
543 FN_BLOCK(6)
544 FN_BLOCK(7)
545 FN_BLOCK(8)
546 FN_BLOCK(9)
547 FN_BLOCK(10)
548 FN_BLOCK(11)
549 FN_BLOCK(12)
550
551 /**
552  * Initialize the function pointers for the callback routines.
553  *
554  * NOTE: If MAX_ARGS or MAX_CALLBACKS changes, the following has to be updated.
555  */
556 #if MAX_CALLBACKS == 16
557 #define FN_A_BLOCK(args) { \
558         (jintLong)FN(0, args), \
559         (jintLong)FN(1, args), \
560         (jintLong)FN(2, args), \
561         (jintLong)FN(3, args), \
562         (jintLong)FN(4, args), \
563         (jintLong)FN(5, args), \
564         (jintLong)FN(6, args), \
565         (jintLong)FN(7, args), \
566         (jintLong)FN(8, args), \
567         (jintLong)FN(9, args), \
568         (jintLong)FN(10, args), \
569         (jintLong)FN(11, args), \
570         (jintLong)FN(12, args), \
571         (jintLong)FN(13, args), \
572         (jintLong)FN(14, args), \
573         (jintLong)FN(15, args), \
574 },
575 #elif MAX_CALLBACKS == 128
576 #define FN_A_BLOCK(args) { \
577         (jintLong)FN(0, args), \
578         (jintLong)FN(1, args), \
579         (jintLong)FN(2, args), \
580         (jintLong)FN(3, args), \
581         (jintLong)FN(4, args), \
582         (jintLong)FN(5, args), \
583         (jintLong)FN(6, args), \
584         (jintLong)FN(7, args), \
585         (jintLong)FN(8, args), \
586         (jintLong)FN(9, args), \
587         (jintLong)FN(10, args), \
588         (jintLong)FN(11, args), \
589         (jintLong)FN(12, args), \
590         (jintLong)FN(13, args), \
591         (jintLong)FN(14, args), \
592         (jintLong)FN(15, args), \
593         (jintLong)FN(16, args), \
594         (jintLong)FN(17, args), \
595         (jintLong)FN(18, args), \
596         (jintLong)FN(19, args), \
597         (jintLong)FN(20, args), \
598         (jintLong)FN(21, args), \
599         (jintLong)FN(22, args), \
600         (jintLong)FN(23, args), \
601         (jintLong)FN(24, args), \
602         (jintLong)FN(25, args), \
603         (jintLong)FN(26, args), \
604         (jintLong)FN(27, args), \
605         (jintLong)FN(28, args), \
606         (jintLong)FN(29, args), \
607         (jintLong)FN(30, args), \
608         (jintLong)FN(31, args), \
609         (jintLong)FN(32, args), \
610         (jintLong)FN(33, args), \
611         (jintLong)FN(34, args), \
612         (jintLong)FN(35, args), \
613         (jintLong)FN(36, args), \
614         (jintLong)FN(37, args), \
615         (jintLong)FN(38, args), \
616         (jintLong)FN(39, args), \
617         (jintLong)FN(40, args), \
618         (jintLong)FN(41, args), \
619         (jintLong)FN(42, args), \
620         (jintLong)FN(43, args), \
621         (jintLong)FN(44, args), \
622         (jintLong)FN(45, args), \
623         (jintLong)FN(46, args), \
624         (jintLong)FN(47, args), \
625         (jintLong)FN(48, args), \
626         (jintLong)FN(49, args), \
627         (jintLong)FN(50, args), \
628         (jintLong)FN(51, args), \
629         (jintLong)FN(52, args), \
630         (jintLong)FN(53, args), \
631         (jintLong)FN(54, args), \
632         (jintLong)FN(55, args), \
633         (jintLong)FN(56, args), \
634         (jintLong)FN(57, args), \
635         (jintLong)FN(58, args), \
636         (jintLong)FN(59, args), \
637         (jintLong)FN(60, args), \
638         (jintLong)FN(61, args), \
639         (jintLong)FN(62, args), \
640         (jintLong)FN(63, args), \
641         (jintLong)FN(64, args), \
642         (jintLong)FN(65, args), \
643         (jintLong)FN(66, args), \
644         (jintLong)FN(67, args), \
645         (jintLong)FN(68, args), \
646         (jintLong)FN(69, args), \
647         (jintLong)FN(70, args), \
648         (jintLong)FN(71, args), \
649         (jintLong)FN(72, args), \
650         (jintLong)FN(73, args), \
651         (jintLong)FN(74, args), \
652         (jintLong)FN(75, args), \
653         (jintLong)FN(76, args), \
654         (jintLong)FN(77, args), \
655         (jintLong)FN(78, args), \
656         (jintLong)FN(79, args), \
657         (jintLong)FN(80, args), \
658         (jintLong)FN(81, args), \
659         (jintLong)FN(82, args), \
660         (jintLong)FN(83, args), \
661         (jintLong)FN(84, args), \
662         (jintLong)FN(85, args), \
663         (jintLong)FN(86, args), \
664         (jintLong)FN(87, args), \
665         (jintLong)FN(88, args), \
666         (jintLong)FN(89, args), \
667         (jintLong)FN(90, args), \
668         (jintLong)FN(91, args), \
669         (jintLong)FN(92, args), \
670         (jintLong)FN(93, args), \
671         (jintLong)FN(94, args), \
672         (jintLong)FN(95, args), \
673         (jintLong)FN(96, args), \
674         (jintLong)FN(97, args), \
675         (jintLong)FN(98, args), \
676         (jintLong)FN(99, args), \
677         (jintLong)FN(100, args), \
678         (jintLong)FN(101, args), \
679         (jintLong)FN(102, args), \
680         (jintLong)FN(103, args), \
681         (jintLong)FN(104, args), \
682         (jintLong)FN(105, args), \
683         (jintLong)FN(106, args), \
684         (jintLong)FN(107, args), \
685         (jintLong)FN(108, args), \
686         (jintLong)FN(109, args), \
687         (jintLong)FN(110, args), \
688         (jintLong)FN(111, args), \
689         (jintLong)FN(112, args), \
690         (jintLong)FN(113, args), \
691         (jintLong)FN(114, args), \
692         (jintLong)FN(115, args), \
693         (jintLong)FN(116, args), \
694         (jintLong)FN(117, args), \
695         (jintLong)FN(118, args), \
696         (jintLong)FN(119, args), \
697         (jintLong)FN(120, args), \
698         (jintLong)FN(121, args), \
699         (jintLong)FN(122, args), \
700         (jintLong)FN(123, args), \
701         (jintLong)FN(124, args), \
702         (jintLong)FN(125, args), \
703         (jintLong)FN(126, args), \
704         (jintLong)FN(127, args), \
705 },
706 #elif MAX_CALLBACKS == 256
707 #define FN_A_BLOCK(args) { \
708         (jintLong)FN(0, args), \
709         (jintLong)FN(1, args), \
710         (jintLong)FN(2, args), \
711         (jintLong)FN(3, args), \
712         (jintLong)FN(4, args), \
713         (jintLong)FN(5, args), \
714         (jintLong)FN(6, args), \
715         (jintLong)FN(7, args), \
716         (jintLong)FN(8, args), \
717         (jintLong)FN(9, args), \
718         (jintLong)FN(10, args), \
719         (jintLong)FN(11, args), \
720         (jintLong)FN(12, args), \
721         (jintLong)FN(13, args), \
722         (jintLong)FN(14, args), \
723         (jintLong)FN(15, args), \
724         (jintLong)FN(16, args), \
725         (jintLong)FN(17, args), \
726         (jintLong)FN(18, args), \
727         (jintLong)FN(19, args), \
728         (jintLong)FN(20, args), \
729         (jintLong)FN(21, args), \
730         (jintLong)FN(22, args), \
731         (jintLong)FN(23, args), \
732         (jintLong)FN(24, args), \
733         (jintLong)FN(25, args), \
734         (jintLong)FN(26, args), \
735         (jintLong)FN(27, args), \
736         (jintLong)FN(28, args), \
737         (jintLong)FN(29, args), \
738         (jintLong)FN(30, args), \
739         (jintLong)FN(31, args), \
740         (jintLong)FN(32, args), \
741         (jintLong)FN(33, args), \
742         (jintLong)FN(34, args), \
743         (jintLong)FN(35, args), \
744         (jintLong)FN(36, args), \
745         (jintLong)FN(37, args), \
746         (jintLong)FN(38, args), \
747         (jintLong)FN(39, args), \
748         (jintLong)FN(40, args), \
749         (jintLong)FN(41, args), \
750         (jintLong)FN(42, args), \
751         (jintLong)FN(43, args), \
752         (jintLong)FN(44, args), \
753         (jintLong)FN(45, args), \
754         (jintLong)FN(46, args), \
755         (jintLong)FN(47, args), \
756         (jintLong)FN(48, args), \
757         (jintLong)FN(49, args), \
758         (jintLong)FN(50, args), \
759         (jintLong)FN(51, args), \
760         (jintLong)FN(52, args), \
761         (jintLong)FN(53, args), \
762         (jintLong)FN(54, args), \
763         (jintLong)FN(55, args), \
764         (jintLong)FN(56, args), \
765         (jintLong)FN(57, args), \
766         (jintLong)FN(58, args), \
767         (jintLong)FN(59, args), \
768         (jintLong)FN(60, args), \
769         (jintLong)FN(61, args), \
770         (jintLong)FN(62, args), \
771         (jintLong)FN(63, args), \
772         (jintLong)FN(64, args), \
773         (jintLong)FN(65, args), \
774         (jintLong)FN(66, args), \
775         (jintLong)FN(67, args), \
776         (jintLong)FN(68, args), \
777         (jintLong)FN(69, args), \
778         (jintLong)FN(70, args), \
779         (jintLong)FN(71, args), \
780         (jintLong)FN(72, args), \
781         (jintLong)FN(73, args), \
782         (jintLong)FN(74, args), \
783         (jintLong)FN(75, args), \
784         (jintLong)FN(76, args), \
785         (jintLong)FN(77, args), \
786         (jintLong)FN(78, args), \
787         (jintLong)FN(79, args), \
788         (jintLong)FN(80, args), \
789         (jintLong)FN(81, args), \
790         (jintLong)FN(82, args), \
791         (jintLong)FN(83, args), \
792         (jintLong)FN(84, args), \
793         (jintLong)FN(85, args), \
794         (jintLong)FN(86, args), \
795         (jintLong)FN(87, args), \
796         (jintLong)FN(88, args), \
797         (jintLong)FN(89, args), \
798         (jintLong)FN(90, args), \
799         (jintLong)FN(91, args), \
800         (jintLong)FN(92, args), \
801         (jintLong)FN(93, args), \
802         (jintLong)FN(94, args), \
803         (jintLong)FN(95, args), \
804         (jintLong)FN(96, args), \
805         (jintLong)FN(97, args), \
806         (jintLong)FN(98, args), \
807         (jintLong)FN(99, args), \
808         (jintLong)FN(100, args), \
809         (jintLong)FN(101, args), \
810         (jintLong)FN(102, args), \
811         (jintLong)FN(103, args), \
812         (jintLong)FN(104, args), \
813         (jintLong)FN(105, args), \
814         (jintLong)FN(106, args), \
815         (jintLong)FN(107, args), \
816         (jintLong)FN(108, args), \
817         (jintLong)FN(109, args), \
818         (jintLong)FN(110, args), \
819         (jintLong)FN(111, args), \
820         (jintLong)FN(112, args), \
821         (jintLong)FN(113, args), \
822         (jintLong)FN(114, args), \
823         (jintLong)FN(115, args), \
824         (jintLong)FN(116, args), \
825         (jintLong)FN(117, args), \
826         (jintLong)FN(118, args), \
827         (jintLong)FN(119, args), \
828         (jintLong)FN(120, args), \
829         (jintLong)FN(121, args), \
830         (jintLong)FN(122, args), \
831         (jintLong)FN(123, args), \
832         (jintLong)FN(124, args), \
833         (jintLong)FN(125, args), \
834         (jintLong)FN(126, args), \
835         (jintLong)FN(127, args), \
836         (jintLong)FN(128, args), \
837         (jintLong)FN(129, args), \
838         (jintLong)FN(130, args), \
839         (jintLong)FN(131, args), \
840         (jintLong)FN(132, args), \
841         (jintLong)FN(133, args), \
842         (jintLong)FN(134, args), \
843         (jintLong)FN(135, args), \
844         (jintLong)FN(136, args), \
845         (jintLong)FN(137, args), \
846         (jintLong)FN(138, args), \
847         (jintLong)FN(139, args), \
848         (jintLong)FN(140, args), \
849         (jintLong)FN(141, args), \
850         (jintLong)FN(142, args), \
851         (jintLong)FN(143, args), \
852         (jintLong)FN(144, args), \
853         (jintLong)FN(145, args), \
854         (jintLong)FN(146, args), \
855         (jintLong)FN(147, args), \
856         (jintLong)FN(148, args), \
857         (jintLong)FN(149, args), \
858         (jintLong)FN(150, args), \
859         (jintLong)FN(151, args), \
860         (jintLong)FN(152, args), \
861         (jintLong)FN(153, args), \
862         (jintLong)FN(154, args), \
863         (jintLong)FN(155, args), \
864         (jintLong)FN(156, args), \
865         (jintLong)FN(157, args), \
866         (jintLong)FN(158, args), \
867         (jintLong)FN(159, args), \
868         (jintLong)FN(160, args), \
869         (jintLong)FN(161, args), \
870         (jintLong)FN(162, args), \
871         (jintLong)FN(163, args), \
872         (jintLong)FN(164, args), \
873         (jintLong)FN(165, args), \
874         (jintLong)FN(166, args), \
875         (jintLong)FN(167, args), \
876         (jintLong)FN(168, args), \
877         (jintLong)FN(169, args), \
878         (jintLong)FN(170, args), \
879         (jintLong)FN(171, args), \
880         (jintLong)FN(172, args), \
881         (jintLong)FN(173, args), \
882         (jintLong)FN(174, args), \
883         (jintLong)FN(175, args), \
884         (jintLong)FN(176, args), \
885         (jintLong)FN(177, args), \
886         (jintLong)FN(178, args), \
887         (jintLong)FN(179, args), \
888         (jintLong)FN(180, args), \
889         (jintLong)FN(181, args), \
890         (jintLong)FN(182, args), \
891         (jintLong)FN(183, args), \
892         (jintLong)FN(184, args), \
893         (jintLong)FN(185, args), \
894         (jintLong)FN(186, args), \
895         (jintLong)FN(187, args), \
896         (jintLong)FN(188, args), \
897         (jintLong)FN(189, args), \
898         (jintLong)FN(190, args), \
899         (jintLong)FN(191, args), \
900         (jintLong)FN(192, args), \
901         (jintLong)FN(193, args), \
902         (jintLong)FN(194, args), \
903         (jintLong)FN(195, args), \
904         (jintLong)FN(196, args), \
905         (jintLong)FN(197, args), \
906         (jintLong)FN(198, args), \
907         (jintLong)FN(199, args), \
908         (jintLong)FN(200, args), \
909         (jintLong)FN(201, args), \
910         (jintLong)FN(202, args), \
911         (jintLong)FN(203, args), \
912         (jintLong)FN(204, args), \
913         (jintLong)FN(205, args), \
914         (jintLong)FN(206, args), \
915         (jintLong)FN(207, args), \
916         (jintLong)FN(208, args), \
917         (jintLong)FN(209, args), \
918         (jintLong)FN(210, args), \
919         (jintLong)FN(211, args), \
920         (jintLong)FN(212, args), \
921         (jintLong)FN(213, args), \
922         (jintLong)FN(214, args), \
923         (jintLong)FN(215, args), \
924         (jintLong)FN(216, args), \
925         (jintLong)FN(217, args), \
926         (jintLong)FN(218, args), \
927         (jintLong)FN(219, args), \
928         (jintLong)FN(220, args), \
929         (jintLong)FN(221, args), \
930         (jintLong)FN(222, args), \
931         (jintLong)FN(223, args), \
932         (jintLong)FN(224, args), \
933         (jintLong)FN(225, args), \
934         (jintLong)FN(226, args), \
935         (jintLong)FN(227, args), \
936         (jintLong)FN(228, args), \
937         (jintLong)FN(229, args), \
938         (jintLong)FN(230, args), \
939         (jintLong)FN(231, args), \
940         (jintLong)FN(232, args), \
941         (jintLong)FN(233, args), \
942         (jintLong)FN(234, args), \
943         (jintLong)FN(235, args), \
944         (jintLong)FN(236, args), \
945         (jintLong)FN(237, args), \
946         (jintLong)FN(238, args), \
947         (jintLong)FN(239, args), \
948         (jintLong)FN(240, args), \
949         (jintLong)FN(241, args), \
950         (jintLong)FN(242, args), \
951         (jintLong)FN(243, args), \
952         (jintLong)FN(244, args), \
953         (jintLong)FN(245, args), \
954         (jintLong)FN(246, args), \
955         (jintLong)FN(247, args), \
956         (jintLong)FN(248, args), \
957         (jintLong)FN(249, args), \
958         (jintLong)FN(250, args), \
959         (jintLong)FN(251, args), \
960         (jintLong)FN(252, args), \
961         (jintLong)FN(253, args), \
962         (jintLong)FN(254, args), \
963         (jintLong)FN(255, args), \
964 },
965 #else
966 #error Invalid MAX_CALLBACKS
967 #endif /* MAX_CALLBACKS == 16 */
968
969 jintLong fnx_array[MAX_ARGS+1][MAX_CALLBACKS] = { 
970         FN_A_BLOCK(0)    
971         FN_A_BLOCK(1)    
972         FN_A_BLOCK(2)    
973         FN_A_BLOCK(3)    
974         FN_A_BLOCK(4)    
975         FN_A_BLOCK(5)    
976         FN_A_BLOCK(6)    
977         FN_A_BLOCK(7)    
978         FN_A_BLOCK(8)    
979         FN_A_BLOCK(9)    
980         FN_A_BLOCK(10)    
981         FN_A_BLOCK(11)    
982         FN_A_BLOCK(12)    
983 };
984
985 #endif /* USE_ASSEMBLER */
986
987 /* --------------- callback class calls --------------- */
988
989 JNIEXPORT jintLong JNICALL CALLBACK_NATIVE(bind)
990   (JNIEnv *env, jclass that, jobject callbackObject, jobject object, jstring method, jstring signature, jint argCount, jboolean isStatic, jboolean isArrayBased, jintLong errorResult)
991 {
992         int i;
993         jmethodID mid = NULL;
994         jclass javaClass = that;
995         const char *methodString = NULL, *sigString = NULL;
996         if (jvm == NULL) (*env)->GetJavaVM(env, &jvm);
997         if (JNI_VERSION == 0) JNI_VERSION = (*env)->GetVersion(env);
998         if (!initialized) {
999                 memset(&callbackData, 0, sizeof(callbackData));
1000                 initialized = 1;
1001         }
1002         if (method) methodString = (const char *) (*env)->GetStringUTFChars(env, method, NULL);
1003         if (signature) sigString = (const char *) (*env)->GetStringUTFChars(env, signature, NULL);
1004         if (object && methodString && sigString) {
1005                 if (isStatic) {
1006                         mid = (*env)->GetStaticMethodID(env, object, methodString, sigString);
1007                 } else {
1008                         javaClass = (*env)->GetObjectClass(env, object);    
1009                         mid = (*env)->GetMethodID(env, javaClass, methodString, sigString);
1010                 }
1011         }
1012         if (method && methodString) (*env)->ReleaseStringUTFChars(env, method, methodString);
1013         if (signature && sigString) (*env)->ReleaseStringUTFChars(env, signature, sigString);
1014         if (mid == 0) goto fail;
1015         for (i=0; i<MAX_CALLBACKS; i++) {
1016                 if (!callbackData[i].callback) {
1017                         if ((callbackData[i].callback = (*env)->NewGlobalRef(env, callbackObject)) == NULL) goto fail;
1018                         if ((callbackData[i].object = (*env)->NewGlobalRef(env, object)) == NULL) goto fail;
1019                         callbackData[i].isStatic = isStatic;
1020                         callbackData[i].isArrayBased = isArrayBased;
1021                         callbackData[i].argCount = argCount;
1022                         callbackData[i].errorResult = errorResult;
1023                         callbackData[i].methodID = mid;
1024 #ifndef USE_ASSEMBLER
1025                         return (jintLong) fnx_array[argCount][i];
1026 #else
1027                         {
1028                         int j = 0, k;
1029                         unsigned char* code;
1030 #ifdef __APPLE__
1031                         int pad = 0;
1032 #endif
1033                         if (callbackCode == NULL) {
1034 #if defined (_WIN32) || defined (_WIN32_WCE)
1035                                 callbackCode = VirtualAlloc(NULL, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
1036                                 if (callbackCode == NULL) return 0;
1037 #else 
1038                                 callbackCode = mmap(NULL, CALLBACK_THUNK_SIZE * MAX_CALLBACKS, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
1039                                 if (callbackCode == MAP_FAILED) return 0;
1040 #endif
1041                         }
1042                         code = (unsigned char *)(callbackCode + (i * CALLBACK_THUNK_SIZE));
1043
1044                         //PUSH EBP - 1 byte
1045                         code[j++] = 0x55;
1046
1047                         //MOV EBP,ESP - 2 bytes
1048                         code[j++] = 0x8b;
1049                         code[j++] = 0xec;
1050
1051 #ifdef __APPLE__
1052                         /* darwin calling conventions require that the stack be aligned on a 16-byte boundary. */
1053                         k = (argCount+3)*sizeof(jintLong);
1054                         pad = ((k + 15) & ~15) - k;
1055                         if (pad > 0) {
1056                                 //SUB ESP,pad - 3 bytes
1057                                 code[j++] = 0x83;
1058                                 code[j++] = 0xec;
1059                                 code[j++] = pad;
1060                         }
1061 #endif
1062
1063                         // 3*argCount bytes
1064                         for (k=(argCount + 1) * sizeof(jintLong); k >= sizeof(jintLong)*2; k -= sizeof(jintLong)) {
1065                                 //PUSH SS:[EBP+k]
1066                                 code[j++] = 0xff;
1067                                 code[j++] = 0x75;
1068                                 code[j++] = k;
1069                         }
1070
1071                         if (i > 127) {
1072                                 //PUSH i - 5 bytes
1073                                 code[j++] = 0x68;
1074                                 code[j++] = ((i >> 0) & 0xFF);
1075                                 code[j++] = ((i >> 8) & 0xFF);
1076                                 code[j++] = ((i >> 16) & 0xFF);
1077                                 code[j++] = ((i >> 24) & 0xFF);
1078                         } else {
1079                                 //PUSH i - 2 bytes
1080                                 code[j++] = 0x6a;
1081                                 code[j++] = i;
1082                         }
1083
1084                         //MOV EAX callback - 1 + sizeof(jintLong) bytes
1085                         code[j++] = 0xb8;
1086                         ((jintLong *)&code[j])[0] = (jintLong)&callback;
1087                         j += sizeof(jintLong);
1088
1089                         //CALL EAX - 2 bytes
1090                         code[j++] = 0xff;
1091                         code[j++] = 0xd0;
1092
1093                         //ADD ESP,(argCount + 1) * sizeof(jintLong) - 3 bytes
1094                         code[j++] = 0x83;
1095                         code[j++] = 0xc4;
1096 #ifdef __APPLE__
1097                         code[j++] = (unsigned char)(pad + ((argCount + 1) * sizeof(jintLong)));
1098 #else
1099                         code[j++] = (unsigned char)((argCount + 1) * sizeof(jintLong));
1100 #endif
1101
1102                         //POP EBP - 1 byte
1103                         code[j++] = 0x5d;
1104
1105 #if defined (_WIN32) || defined (_WIN32_WCE)
1106                         //RETN argCount * sizeof(jintLong) - 3 bytes
1107                         code[j++] = 0xc2;
1108                         code[j++] = (unsigned char)(argCount * sizeof(jintLong));
1109                         code[j++] = 0x00;
1110 #else
1111                         //RETN - 1 byte
1112                         code[j++] = 0xc3;
1113 #endif
1114
1115                         if (j > CALLBACK_THUNK_SIZE) {
1116                                 jclass errorClass = (*env)->FindClass(env, "java/lang/Error");
1117                                 (*env)->ThrowNew(env, errorClass, "Callback thunk overflow");
1118                         }
1119
1120                         return (jintLong)code;
1121                         }
1122 #endif /* USE_ASSEMBLER */
1123                 }
1124         }
1125 fail:
1126     return 0;
1127 }
1128
1129 JNIEXPORT void JNICALL CALLBACK_NATIVE(unbind)
1130   (JNIEnv *env, jclass that, jobject callback)
1131 {
1132         int i;
1133     for (i=0; i<MAX_CALLBACKS; i++) {
1134         if (callbackData[i].callback != NULL && (*env)->IsSameObject(env, callback, callbackData[i].callback)) {
1135             if (callbackData[i].callback != NULL) (*env)->DeleteGlobalRef(env, callbackData[i].callback);
1136             if (callbackData[i].object != NULL) (*env)->DeleteGlobalRef(env, callbackData[i].object);
1137             memset(&callbackData[i], 0, sizeof(CALLBACK_DATA));
1138         }
1139     }
1140 }
1141
1142 JNIEXPORT jboolean JNICALL CALLBACK_NATIVE(getEnabled)
1143   (JNIEnv *env, jclass that)
1144 {
1145         return (jboolean)callbackEnabled;
1146 }
1147
1148 JNIEXPORT jint JNICALL CALLBACK_NATIVE(getEntryCount)
1149   (JNIEnv *env, jclass that)
1150 {
1151         return (jint)callbackEntryCount;
1152 }
1153
1154 JNIEXPORT void JNICALL CALLBACK_NATIVE(setEnabled)
1155   (JNIEnv *env, jclass that, jboolean enable)
1156 {
1157         callbackEnabled = enable;
1158 }
1159
1160 JNIEXPORT void JNICALL CALLBACK_NATIVE(reset)
1161   (JNIEnv *env, jclass that)
1162 {
1163     memset((void *)&callbackData, 0, sizeof(callbackData));
1164 }
1165
1166 jintLong callback(int index, ...)
1167 {
1168         if (!callbackEnabled) return 0;
1169
1170         {
1171         JNIEnv *env = NULL;
1172         jmethodID mid = callbackData[index].methodID;
1173         jobject object = callbackData[index].object;
1174         jboolean isStatic = callbackData[index].isStatic;
1175         jboolean isArrayBased = callbackData[index].isArrayBased;
1176         jint argCount = callbackData[index].argCount;
1177         jintLong result = callbackData[index].errorResult;
1178         jthrowable ex;
1179         int detach = 0;
1180         va_list vl;
1181
1182 #ifdef DEBUG_CALL_PRINTS
1183         fprintf(stderr, "* callback starting %d\n", counter++);
1184 #endif
1185
1186 #ifdef JNI_VERSION_1_2
1187         if (IS_JNI_1_2) {
1188                 (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2);
1189         }
1190 #endif
1191         
1192 #ifdef JNI_VERSION_1_4
1193         if (env == NULL) {
1194                 if (JNI_VERSION >= JNI_VERSION_1_4) {
1195                         (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&env, NULL);
1196                 }
1197         }
1198 #endif
1199         
1200         if (env == NULL) {
1201                 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
1202                 if (IS_JNI_1_2) detach = 1;
1203         }
1204         
1205         /* If the current thread is not attached to the VM, it is not possible to call into the VM */
1206         if (env == NULL) {
1207 #ifdef DEBUG_CALL_PRINTS
1208                 fprintf(stderr, "* could not get env\n");
1209 #endif
1210                 goto noEnv;
1211         }
1212
1213         /* If an exception has occurred in previous callbacks do not call into the VM. */
1214         if ((ex = (*env)->ExceptionOccurred(env))) {
1215                 (*env)->DeleteLocalRef(env, ex);
1216                 goto done;
1217         }
1218
1219         /* Call into the VM. */
1220         ATOMIC_INC(callbackEntryCount);
1221         va_start(vl, index);
1222         if (isArrayBased) {
1223                 int i;
1224                 jintLongArray argsArray = (*env)->NewIntLongArray(env, argCount);
1225                 if (argsArray != NULL) {
1226                         jintLong *elements = (*env)->GetIntLongArrayElements(env, argsArray, NULL);
1227                         if (elements != NULL) {
1228                                 for (i=0; i<argCount; i++) {
1229                                         elements[i] = va_arg(vl, jintLong); 
1230                                 }
1231                                 (*env)->ReleaseIntLongArrayElements(env, argsArray, elements, 0);
1232                                 if (isStatic) {
1233                                         result = (*env)->CallStaticIntLongMethod(env, object, mid, argsArray);
1234                                 } else {
1235                                         result = (*env)->CallIntLongMethod(env, object, mid, argsArray);
1236                                 }
1237                         }
1238                         /*
1239                         * This function may be called many times before returning to Java,
1240                         * explicitly delete local references to avoid GP's in certain VMs.
1241                         */
1242                         (*env)->DeleteLocalRef(env, argsArray);
1243                 }
1244         } else {
1245                 if (isStatic) {
1246                         result = (*env)->CallStaticIntLongMethodV(env, object, mid, vl);
1247                 } else {
1248                         result = (*env)->CallIntLongMethodV(env, object, mid, vl);
1249                 }
1250         }
1251         va_end(vl);
1252         ATOMIC_DEC(callbackEntryCount);
1253
1254 done:
1255         /* If an exception has occurred in Java, return the error result. */
1256         if ((ex = (*env)->ExceptionOccurred(env))) {
1257                 (*env)->DeleteLocalRef(env, ex);
1258 #ifdef DEBUG_CALL_PRINTS
1259                 fprintf(stderr, "* java exception occurred\n");
1260                 (*env)->ExceptionDescribe(env);
1261 #endif
1262                 result = callbackData[index].errorResult;
1263         }
1264
1265         if (detach) {
1266                 (*jvm)->DetachCurrentThread(jvm);
1267                 env = NULL;
1268         }
1269
1270 noEnv:
1271
1272 #ifdef DEBUG_CALL_PRINTS
1273         fprintf(stderr, "* callback exiting %d\n", --counter);
1274 #endif
1275
1276         return result;
1277         }
1278 }
1279
1280 /* ------------- callback class calls end --------------- */