1 /*******************************************************************************
2 * Copyright (c) 2000, 2012 IBM Corporation and others.
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/
9 * SPDX-License-Identifier: EPL-2.0
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
16 * Callback implementation.
21 #ifndef CALLBACK_NATIVE
22 #define CALLBACK_NATIVE(func) Java_org_eclipse_swt_internal_Callback_##func
25 /* define this to print out debug statements */
26 /* #define DEBUG_CALL_PRINTS */
28 /* --------------- callback globals ----------------- */
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;
37 #ifdef DEBUG_CALL_PRINTS
38 static int counter = 0;
42 #include <libkern/OSAtomic.h>
43 #define ATOMIC_INC(value) OSAtomicIncrement32(&value);
44 #define ATOMIC_DEC(value) OSAtomicDecrement32(&value);
46 #define ATOMIC_INC(value) value++;
47 #define ATOMIC_DEC(value) value--;
50 jintLong callback(int index, ...);
54 #if !(defined (_WIN32) || defined (_WIN32_WCE))
58 static unsigned char *callbackCode = NULL;
59 #define CALLBACK_THUNK_SIZE 64
63 /* --------------- callback functions --------------- */
66 /* Function name from index and number of arguments */
67 #define FN(index, args) fn##index##_##args
72 * NOTE: If the maximum number of arguments changes (MAX_ARGS), the number
73 * of function templates has to change accordingly.
76 /* Function template with no arguments */
77 #define FN_0(index) RETURN_TYPE FN(index, 0)() { return RETURN_CAST callback(index); }
79 /* Function template with 1 argument */
80 #define FN_1(index) RETURN_TYPE FN(index, 1)(jintLong p1) { return RETURN_CAST callback(index, p1); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
116 * Define all functions with the specified number of arguments.
118 * NOTE: If the maximum number of callbacks changes (MAX_CALLBACKS),
119 * this macro has to be updated.
121 #if MAX_CALLBACKS == 16
122 #define FN_BLOCK(args) \
139 #elif MAX_CALLBACKS == 128
140 #define FN_BLOCK(args) \
269 #elif MAX_CALLBACKS == 256
270 #define FN_BLOCK(args) \
528 #error Invalid MAX_CALLBACKS
529 #endif /* MAX_CALLBACKS == 16 */
532 * Define all callback functions.
534 * NOTE: If the maximum number of arguments changes (MAX_ARGS), the following
535 * has to change accordinglly.
552 * Initialize the function pointers for the callback routines.
554 * NOTE: If MAX_ARGS or MAX_CALLBACKS changes, the following has to be updated.
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), \
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), \
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), \
966 #error Invalid MAX_CALLBACKS
967 #endif /* MAX_CALLBACKS == 16 */
969 jintLong fnx_array[MAX_ARGS+1][MAX_CALLBACKS] = {
985 #endif /* USE_ASSEMBLER */
987 /* --------------- callback class calls --------------- */
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)
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);
999 memset(&callbackData, 0, sizeof(callbackData));
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) {
1006 mid = (*env)->GetStaticMethodID(env, object, methodString, sigString);
1008 javaClass = (*env)->GetObjectClass(env, object);
1009 mid = (*env)->GetMethodID(env, javaClass, methodString, sigString);
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];
1029 unsigned char* code;
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;
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;
1042 code = (unsigned char *)(callbackCode + (i * CALLBACK_THUNK_SIZE));
1047 //MOV EBP,ESP - 2 bytes
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;
1056 //SUB ESP,pad - 3 bytes
1064 for (k=(argCount + 1) * sizeof(jintLong); k >= sizeof(jintLong)*2; k -= sizeof(jintLong)) {
1074 code[j++] = ((i >> 0) & 0xFF);
1075 code[j++] = ((i >> 8) & 0xFF);
1076 code[j++] = ((i >> 16) & 0xFF);
1077 code[j++] = ((i >> 24) & 0xFF);
1084 //MOV EAX callback - 1 + sizeof(jintLong) bytes
1086 ((jintLong *)&code[j])[0] = (jintLong)&callback;
1087 j += sizeof(jintLong);
1089 //CALL EAX - 2 bytes
1093 //ADD ESP,(argCount + 1) * sizeof(jintLong) - 3 bytes
1097 code[j++] = (unsigned char)(pad + ((argCount + 1) * sizeof(jintLong)));
1099 code[j++] = (unsigned char)((argCount + 1) * sizeof(jintLong));
1105 #if defined (_WIN32) || defined (_WIN32_WCE)
1106 //RETN argCount * sizeof(jintLong) - 3 bytes
1108 code[j++] = (unsigned char)(argCount * sizeof(jintLong));
1115 if (j > CALLBACK_THUNK_SIZE) {
1116 jclass errorClass = (*env)->FindClass(env, "java/lang/Error");
1117 (*env)->ThrowNew(env, errorClass, "Callback thunk overflow");
1120 return (jintLong)code;
1122 #endif /* USE_ASSEMBLER */
1129 JNIEXPORT void JNICALL CALLBACK_NATIVE(unbind)
1130 (JNIEnv *env, jclass that, jobject callback)
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));
1142 JNIEXPORT jboolean JNICALL CALLBACK_NATIVE(getEnabled)
1143 (JNIEnv *env, jclass that)
1145 return (jboolean)callbackEnabled;
1148 JNIEXPORT jint JNICALL CALLBACK_NATIVE(getEntryCount)
1149 (JNIEnv *env, jclass that)
1151 return (jint)callbackEntryCount;
1154 JNIEXPORT void JNICALL CALLBACK_NATIVE(setEnabled)
1155 (JNIEnv *env, jclass that, jboolean enable)
1157 callbackEnabled = enable;
1160 JNIEXPORT void JNICALL CALLBACK_NATIVE(reset)
1161 (JNIEnv *env, jclass that)
1163 memset((void *)&callbackData, 0, sizeof(callbackData));
1166 jintLong callback(int index, ...)
1168 if (!callbackEnabled) return 0;
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;
1182 #ifdef DEBUG_CALL_PRINTS
1183 fprintf(stderr, "* callback starting %d\n", counter++);
1186 #ifdef JNI_VERSION_1_2
1188 (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2);
1192 #ifdef JNI_VERSION_1_4
1194 if (JNI_VERSION >= JNI_VERSION_1_4) {
1195 (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&env, NULL);
1201 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
1202 if (IS_JNI_1_2) detach = 1;
1205 /* If the current thread is not attached to the VM, it is not possible to call into the VM */
1207 #ifdef DEBUG_CALL_PRINTS
1208 fprintf(stderr, "* could not get env\n");
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);
1219 /* Call into the VM. */
1220 ATOMIC_INC(callbackEntryCount);
1221 va_start(vl, index);
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);
1231 (*env)->ReleaseIntLongArrayElements(env, argsArray, elements, 0);
1233 result = (*env)->CallStaticIntLongMethod(env, object, mid, argsArray);
1235 result = (*env)->CallIntLongMethod(env, object, mid, argsArray);
1239 * This function may be called many times before returning to Java,
1240 * explicitly delete local references to avoid GP's in certain VMs.
1242 (*env)->DeleteLocalRef(env, argsArray);
1246 result = (*env)->CallStaticIntLongMethodV(env, object, mid, vl);
1248 result = (*env)->CallIntLongMethodV(env, object, mid, vl);
1252 ATOMIC_DEC(callbackEntryCount);
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);
1262 result = callbackData[index].errorResult;
1266 (*jvm)->DetachCurrentThread(jvm);
1272 #ifdef DEBUG_CALL_PRINTS
1273 fprintf(stderr, "* callback exiting %d\n", --counter);
1280 /* ------------- callback class calls end --------------- */