Line data Source code
1 : /* src/native/jni.cpp - implementation of the Java Native Interface functions
2 :
3 : Copyright (C) 1996-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 :
26 : #include "config.h"
27 :
28 : #include <cassert>
29 : #include <cstring>
30 : #include <stdint.h>
31 :
32 : #include "mm/gc.hpp"
33 : #include "mm/memory.hpp"
34 :
35 : #include "native/jni.hpp"
36 : #include "native/llni.hpp"
37 : #include "native/localref.hpp"
38 : #include "native/native.hpp"
39 :
40 : #if defined(ENABLE_JVMTI)
41 : # include "native/jvmti/cacaodbg.h"
42 : #endif
43 :
44 : #include "threads/lock.hpp"
45 : #include "threads/mutex.hpp"
46 : #include "threads/thread.hpp"
47 :
48 : #include "toolbox/logging.hpp"
49 : #include "toolbox/hashtable.hpp"
50 :
51 : #include "vm/array.hpp"
52 : #include "vm/exceptions.hpp"
53 : #include "vm/global.hpp"
54 : #include "vm/globals.hpp"
55 : #include "vm/initialize.hpp"
56 : #include "vm/javaobjects.hpp"
57 : #include "vm/loader.hpp"
58 : #include "vm/options.hpp"
59 : #include "vm/primitive.hpp"
60 : #include "vm/resolve.hpp"
61 : #include "vm/statistics.hpp"
62 : #include "vm/string.hpp"
63 : #include "vm/types.hpp"
64 : #include "vm/vm.hpp"
65 :
66 : #include "vm/jit/builtin.hpp"
67 : #include "vm/jit/stacktrace.hpp"
68 :
69 :
70 : /* debug **********************************************************************/
71 :
72 : #if !defined(NDEBUG)
73 :
74 : # define TRACEJNICALLS(x) \
75 : do { \
76 : if (opt_TraceJNICalls) { \
77 : log_println x; \
78 : } \
79 : } while (0)
80 :
81 : # define TRACEJNICALLSENTER(x) \
82 : do { \
83 : if (opt_TraceJNICalls) { \
84 : log_start(); \
85 : log_print x; \
86 : } \
87 : } while (0)
88 :
89 : # define TRACEJNICALLSEXIT(x) \
90 : do { \
91 : if (opt_TraceJNICalls) { \
92 : log_print x; \
93 : log_finish(); \
94 : } \
95 : } while (0)
96 :
97 : #else
98 :
99 : # define TRACEJNICALLS(x)
100 : # define TRACEJNICALLSENTER(x)
101 : # define TRACEJNICALLSEXIT(x)
102 :
103 : #endif
104 :
105 : STAT_REGISTER_GROUP(function_call_stat,"function calls","Function call statistics")
106 : STAT_REGISTER_GROUP_VAR(u8,count_jni_callXmethod_calls,0,"jni callXmethod calls","Number of jni->CallXMethod function invokations",function_call_stat)
107 : STAT_REGISTER_GROUP_VAR(u8,count_jni_calls,0,"jni calls","Overall number of jni invokations",function_call_stat)
108 :
109 : /* global variables ***********************************************************/
110 :
111 : /* global reference table *****************************************************/
112 :
113 : /* hashsize must be power of 2 */
114 :
115 : #define HASHTABLE_GLOBAL_REF_SIZE 64 /* initial size of globalref-hash */
116 :
117 : static hashtable *hashtable_global_ref; /* hashtable for globalrefs */
118 :
119 :
120 : /* direct buffer stuff ********************************************************/
121 :
122 : #if defined(ENABLE_JAVASE)
123 : static classinfo *class_java_nio_Buffer;
124 :
125 : # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
126 :
127 : static classinfo *class_java_nio_DirectByteBufferImpl;
128 : static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
129 :
130 : # if SIZEOF_VOID_P == 8
131 : static classinfo *class_gnu_classpath_Pointer64;
132 : # else
133 : static classinfo *class_gnu_classpath_Pointer32;
134 : # endif
135 :
136 : static methodinfo *dbbirw_init;
137 :
138 : # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
139 :
140 : static classinfo *class_sun_nio_ch_DirectBuffer;
141 : static classinfo *class_java_nio_DirectByteBuffer;
142 :
143 : static methodinfo *dbb_init;
144 :
145 : # endif
146 : #endif
147 :
148 :
149 : /* some forward declarations **************************************************/
150 :
151 : extern "C" {
152 : jobject jni_NewLocalRef(JNIEnv *env, jobject ref);
153 : }
154 :
155 :
156 : #ifdef ENABLE_STATISTICS
157 : /* jnicallXmethodinvokation ***************************************************
158 :
159 : increments the jni CallXMethod invokation count by one
160 :
161 : *******************************************************************************/
162 :
163 : inline void jnicallXmethodnvokation(void)
164 : {
165 : /* XXX do locking here */
166 : STATISTICS(count_jni_callXmethod_calls++);
167 : }
168 :
169 :
170 : /* jniinvokation *************************************************************
171 :
172 : increments the jni overall invokation count by one
173 :
174 : *******************************************************************************/
175 :
176 : inline void jniinvokation(void)
177 : {
178 : /* XXX do locking here */
179 : STATISTICS(count_jni_calls++);
180 : }
181 : #endif // ENABLE_STATISTICS
182 :
183 :
184 : /* jni_init ********************************************************************
185 :
186 : Initialize the JNI subsystem.
187 :
188 : *******************************************************************************/
189 :
190 163 : bool jni_init(void)
191 : {
192 163 : TRACESUBSYSTEMINITIALIZATION("jni_init");
193 :
194 : /* create global ref hashtable */
195 :
196 163 : hashtable_global_ref = NEW(hashtable);
197 :
198 163 : hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
199 :
200 :
201 : #if defined(ENABLE_JAVASE)
202 : /* Direct buffer stuff. */
203 :
204 163 : if (!(class_java_nio_Buffer =
205 : load_class_bootstrap(Utf8String::from_utf8("java/nio/Buffer"))) ||
206 : !link_class(class_java_nio_Buffer))
207 0 : return false;
208 :
209 : # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
210 :
211 163 : if (!(class_java_nio_DirectByteBufferImpl =
212 : load_class_bootstrap(Utf8String::from_utf8("java/nio/DirectByteBufferImpl"))) ||
213 : !link_class(class_java_nio_DirectByteBufferImpl))
214 0 : return false;
215 :
216 163 : if (!(class_java_nio_DirectByteBufferImpl_ReadWrite =
217 : load_class_bootstrap(Utf8String::from_utf8("java/nio/DirectByteBufferImpl$ReadWrite"))) ||
218 : !link_class(class_java_nio_DirectByteBufferImpl_ReadWrite))
219 0 : return false;
220 :
221 163 : if (!(dbbirw_init =
222 : class_resolvemethod(class_java_nio_DirectByteBufferImpl_ReadWrite,
223 : utf8::init,
224 : Utf8String::from_utf8("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
225 0 : return false;
226 :
227 : # if SIZEOF_VOID_P == 8
228 163 : if (!(class_gnu_classpath_Pointer64 =
229 : load_class_bootstrap(Utf8String::from_utf8("gnu/classpath/Pointer64"))) ||
230 : !link_class(class_gnu_classpath_Pointer64))
231 0 : return false;
232 : # else
233 : if (!(class_gnu_classpath_Pointer32 =
234 : load_class_bootstrap(Utf8String::from_utf8("gnu/classpath/Pointer32"))) ||
235 : !link_class(class_gnu_classpath_Pointer32))
236 : return false;
237 : # endif
238 :
239 : # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
240 :
241 : if (!(class_sun_nio_ch_DirectBuffer =
242 : load_class_bootstrap(Utf8String::from_utf8("sun/nio/ch/DirectBuffer"))))
243 : vm_abort("jni_init: loading sun/nio/ch/DirectBuffer failed");
244 :
245 : if (!link_class(class_sun_nio_ch_DirectBuffer))
246 : vm_abort("jni_init: linking sun/nio/ch/DirectBuffer failed");
247 :
248 : if (!(class_java_nio_DirectByteBuffer =
249 : load_class_bootstrap(Utf8String::from_utf8("java/nio/DirectByteBuffer"))))
250 : vm_abort("jni_init: loading java/nio/DirectByteBuffer failed");
251 :
252 : if (!link_class(class_java_nio_DirectByteBuffer))
253 : vm_abort("jni_init: linking java/nio/DirectByteBuffer failed");
254 :
255 : if (!(dbb_init =
256 : class_resolvemethod(class_java_nio_DirectByteBuffer,
257 : utf8::init,
258 : Utf8String::from_utf8("(JI)V"))))
259 : vm_abort("jni_init: resolving java/nio/DirectByteBuffer.init(JI)V failed");
260 :
261 : # endif
262 :
263 : #endif /* defined(ENABLE_JAVASE) */
264 :
265 163 : return true;
266 : }
267 :
268 :
269 : /* jni_version_check ***********************************************************
270 :
271 : Check if the given JNI version is supported.
272 :
273 : IN:
274 : version....JNI version to check
275 :
276 : RETURN VALUE:
277 : true.......supported
278 : false......not supported
279 :
280 : *******************************************************************************/
281 :
282 588 : bool jni_version_check(int version)
283 : {
284 588 : switch (version) {
285 : case JNI_VERSION_1_1:
286 : case JNI_VERSION_1_2:
287 : case JNI_VERSION_1_4:
288 : case JNI_VERSION_1_6:
289 588 : return true;
290 : default:
291 0 : return false;
292 : }
293 : }
294 :
295 :
296 : /* _Jv_jni_CallObjectMethod ****************************************************
297 :
298 : Internal function to call Java Object methods.
299 :
300 : *******************************************************************************/
301 :
302 284620 : static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
303 : vftbl_t *vftbl,
304 : methodinfo *m, va_list ap)
305 : {
306 : methodinfo *resm;
307 : java_handle_t *ro;
308 :
309 : STATISTICS(jniinvokation());
310 :
311 284620 : if (m == NULL) {
312 0 : exceptions_throw_nullpointerexception();
313 0 : return NULL;
314 : }
315 :
316 : /* Class initialization is done by the JIT compiler. This is ok
317 : since a static method always belongs to the declaring class. */
318 :
319 284620 : if (m->flags & ACC_STATIC) {
320 : /* For static methods we reset the object. */
321 :
322 0 : if (o != NULL)
323 0 : o = NULL;
324 :
325 : /* for convenience */
326 :
327 0 : resm = m;
328 :
329 : } else {
330 : /* For instance methods we make a virtual function table lookup. */
331 :
332 284620 : resm = method_vftbl_lookup(vftbl, m);
333 : }
334 :
335 : STATISTICS(jnicallXmethodnvokation());
336 :
337 284620 : ro = vm_call_method_valist(resm, o, ap);
338 :
339 284620 : return ro;
340 : }
341 :
342 :
343 : /* _Jv_jni_CallObjectMethodA ***************************************************
344 :
345 : Internal function to call Java Object methods.
346 :
347 : *******************************************************************************/
348 :
349 0 : static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
350 : vftbl_t *vftbl,
351 : methodinfo *m,
352 : const jvalue *args)
353 : {
354 : methodinfo *resm;
355 : java_handle_t *ro;
356 :
357 : STATISTICS(jniinvokation());
358 :
359 0 : if (m == NULL) {
360 0 : exceptions_throw_nullpointerexception();
361 0 : return NULL;
362 : }
363 :
364 : /* Class initialization is done by the JIT compiler. This is ok
365 : since a static method always belongs to the declaring class. */
366 :
367 0 : if (m->flags & ACC_STATIC) {
368 : /* For static methods we reset the object. */
369 :
370 0 : if (o != NULL)
371 0 : o = NULL;
372 :
373 : /* for convenience */
374 :
375 0 : resm = m;
376 :
377 : } else {
378 : /* For instance methods we make a virtual function table lookup. */
379 :
380 0 : resm = method_vftbl_lookup(vftbl, m);
381 : }
382 :
383 : STATISTICS(jnicallXmethodnvokation());
384 :
385 0 : ro = vm_call_method_jvalue(resm, o, args);
386 :
387 0 : return ro;
388 : }
389 :
390 :
391 : /* _Jv_jni_CallIntMethod *******************************************************
392 :
393 : Internal function to call Java integer class methods (boolean,
394 : byte, char, short, int).
395 :
396 : *******************************************************************************/
397 :
398 381225 : static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
399 : methodinfo *m, va_list ap)
400 : {
401 : methodinfo *resm;
402 : jint i;
403 :
404 : STATISTICS(jniinvokation());
405 :
406 381225 : if (m == NULL) {
407 0 : exceptions_throw_nullpointerexception();
408 0 : return 0;
409 : }
410 :
411 : /* Class initialization is done by the JIT compiler. This is ok
412 : since a static method always belongs to the declaring class. */
413 :
414 381225 : if (m->flags & ACC_STATIC) {
415 : /* For static methods we reset the object. */
416 :
417 1601 : if (o != NULL)
418 0 : o = NULL;
419 :
420 : /* for convenience */
421 :
422 1601 : resm = m;
423 :
424 : } else {
425 : /* For instance methods we make a virtual function table lookup. */
426 :
427 379624 : resm = method_vftbl_lookup(vftbl, m);
428 : }
429 :
430 : STATISTICS(jnicallXmethodnvokation());
431 :
432 381225 : i = vm_call_method_int_valist(resm, o, ap);
433 :
434 381225 : return i;
435 : }
436 :
437 :
438 : /* _Jv_jni_CallIntMethodA ******************************************************
439 :
440 : Internal function to call Java integer class methods (boolean,
441 : byte, char, short, int).
442 :
443 : *******************************************************************************/
444 :
445 0 : static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
446 : methodinfo *m, const jvalue *args)
447 : {
448 : methodinfo *resm;
449 : jint i;
450 :
451 : STATISTICS(jniinvokation());
452 :
453 0 : if (m == NULL) {
454 0 : exceptions_throw_nullpointerexception();
455 0 : return 0;
456 : }
457 :
458 : /* Class initialization is done by the JIT compiler. This is ok
459 : since a static method always belongs to the declaring class. */
460 :
461 0 : if (m->flags & ACC_STATIC) {
462 : /* For static methods we reset the object. */
463 :
464 0 : if (o != NULL)
465 0 : o = NULL;
466 :
467 : /* for convenience */
468 :
469 0 : resm = m;
470 :
471 : } else {
472 : /* For instance methods we make a virtual function table lookup. */
473 :
474 0 : resm = method_vftbl_lookup(vftbl, m);
475 : }
476 :
477 : STATISTICS(jnicallXmethodnvokation());
478 :
479 0 : i = vm_call_method_int_jvalue(resm, o, args);
480 :
481 0 : return i;
482 : }
483 :
484 :
485 : /* _Jv_jni_CallLongMethod ******************************************************
486 :
487 : Internal function to call Java long methods.
488 :
489 : *******************************************************************************/
490 :
491 0 : static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
492 : methodinfo *m, va_list ap)
493 : {
494 : methodinfo *resm;
495 : jlong l;
496 :
497 : STATISTICS(jniinvokation());
498 :
499 0 : if (m == NULL) {
500 0 : exceptions_throw_nullpointerexception();
501 0 : return 0;
502 : }
503 :
504 : /* Class initialization is done by the JIT compiler. This is ok
505 : since a static method always belongs to the declaring class. */
506 :
507 0 : if (m->flags & ACC_STATIC) {
508 : /* For static methods we reset the object. */
509 :
510 0 : if (o != NULL)
511 0 : o = NULL;
512 :
513 : /* for convenience */
514 :
515 0 : resm = m;
516 :
517 : } else {
518 : /* For instance methods we make a virtual function table lookup. */
519 :
520 0 : resm = method_vftbl_lookup(vftbl, m);
521 : }
522 :
523 : STATISTICS(jnicallXmethodnvokation());
524 :
525 0 : l = vm_call_method_long_valist(resm, o, ap);
526 :
527 0 : return l;
528 : }
529 :
530 :
531 : /* _Jv_jni_CallLongMethodA *****************************************************
532 :
533 : Internal function to call Java long methods.
534 :
535 : *******************************************************************************/
536 :
537 0 : static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
538 : methodinfo *m, const jvalue *args)
539 : {
540 : methodinfo *resm;
541 : jlong l;
542 :
543 : STATISTICS(jniinvokation());
544 :
545 0 : if (m == NULL) {
546 0 : exceptions_throw_nullpointerexception();
547 0 : return 0;
548 : }
549 :
550 : /* Class initialization is done by the JIT compiler. This is ok
551 : since a static method always belongs to the declaring class. */
552 :
553 0 : if (m->flags & ACC_STATIC) {
554 : /* For static methods we reset the object. */
555 :
556 0 : if (o != NULL)
557 0 : o = NULL;
558 :
559 : /* for convenience */
560 :
561 0 : resm = m;
562 : }
563 : else {
564 : /* For instance methods we make a virtual function table lookup. */
565 :
566 0 : resm = method_vftbl_lookup(vftbl, m);
567 : }
568 :
569 : STATISTICS(jnicallXmethodnvokation());
570 :
571 0 : l = vm_call_method_long_jvalue(resm, o, args);
572 :
573 0 : return l;
574 : }
575 :
576 :
577 : /* _Jv_jni_CallFloatMethod *****************************************************
578 :
579 : Internal function to call Java float methods.
580 :
581 : *******************************************************************************/
582 :
583 0 : static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
584 : methodinfo *m, va_list ap)
585 : {
586 : methodinfo *resm;
587 : jfloat f;
588 :
589 : /* Class initialization is done by the JIT compiler. This is ok
590 : since a static method always belongs to the declaring class. */
591 :
592 0 : if (m->flags & ACC_STATIC) {
593 : /* For static methods we reset the object. */
594 :
595 0 : if (o != NULL)
596 0 : o = NULL;
597 :
598 : /* for convenience */
599 :
600 0 : resm = m;
601 :
602 : } else {
603 : /* For instance methods we make a virtual function table lookup. */
604 :
605 0 : resm = method_vftbl_lookup(vftbl, m);
606 : }
607 :
608 : STATISTICS(jnicallXmethodnvokation());
609 :
610 0 : f = vm_call_method_float_valist(resm, o, ap);
611 :
612 0 : return f;
613 : }
614 :
615 :
616 : /* _Jv_jni_CallFloatMethodA ****************************************************
617 :
618 : Internal function to call Java float methods.
619 :
620 : *******************************************************************************/
621 :
622 0 : static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
623 : methodinfo *m, const jvalue *args)
624 : {
625 : methodinfo *resm;
626 : jfloat f;
627 :
628 : /* Class initialization is done by the JIT compiler. This is ok
629 : since a static method always belongs to the declaring class. */
630 :
631 0 : if (m->flags & ACC_STATIC) {
632 : /* For static methods we reset the object. */
633 :
634 0 : if (o != NULL)
635 0 : o = NULL;
636 :
637 : /* for convenience */
638 :
639 0 : resm = m;
640 : }
641 : else {
642 : /* For instance methods we make a virtual function table lookup. */
643 :
644 0 : resm = method_vftbl_lookup(vftbl, m);
645 : }
646 :
647 : STATISTICS(jnicallXmethodnvokation());
648 :
649 0 : f = vm_call_method_float_jvalue(resm, o, args);
650 :
651 0 : return f;
652 : }
653 :
654 :
655 : /* _Jv_jni_CallDoubleMethod ****************************************************
656 :
657 : Internal function to call Java double methods.
658 :
659 : *******************************************************************************/
660 :
661 0 : static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
662 : methodinfo *m, va_list ap)
663 : {
664 : methodinfo *resm;
665 : jdouble d;
666 :
667 : /* Class initialization is done by the JIT compiler. This is ok
668 : since a static method always belongs to the declaring class. */
669 :
670 0 : if (m->flags & ACC_STATIC) {
671 : /* For static methods we reset the object. */
672 :
673 0 : if (o != NULL)
674 0 : o = NULL;
675 :
676 : /* for convenience */
677 :
678 0 : resm = m;
679 :
680 : } else {
681 : /* For instance methods we make a virtual function table lookup. */
682 :
683 0 : resm = method_vftbl_lookup(vftbl, m);
684 : }
685 :
686 0 : d = vm_call_method_double_valist(resm, o, ap);
687 :
688 0 : return d;
689 : }
690 :
691 :
692 : /* _Jv_jni_CallDoubleMethodA ***************************************************
693 :
694 : Internal function to call Java double methods.
695 :
696 : *******************************************************************************/
697 :
698 0 : static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
699 : methodinfo *m, const jvalue *args)
700 : {
701 : methodinfo *resm;
702 : jdouble d;
703 :
704 : /* Class initialization is done by the JIT compiler. This is ok
705 : since a static method always belongs to the declaring class. */
706 :
707 0 : if (m->flags & ACC_STATIC) {
708 : /* For static methods we reset the object. */
709 :
710 0 : if (o != NULL)
711 0 : o = NULL;
712 :
713 : /* for convenience */
714 :
715 0 : resm = m;
716 : }
717 : else {
718 : /* For instance methods we make a virtual function table lookup. */
719 :
720 0 : resm = method_vftbl_lookup(vftbl, m);
721 : }
722 :
723 0 : d = vm_call_method_double_jvalue(resm, o, args);
724 :
725 0 : return d;
726 : }
727 :
728 :
729 : /* _Jv_jni_CallVoidMethod ******************************************************
730 :
731 : Internal function to call Java void methods.
732 :
733 : *******************************************************************************/
734 :
735 37 : static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
736 : methodinfo *m, va_list ap)
737 : {
738 : methodinfo *resm;
739 :
740 37 : if (m == NULL) {
741 0 : exceptions_throw_nullpointerexception();
742 0 : return;
743 : }
744 :
745 : /* Class initialization is done by the JIT compiler. This is ok
746 : since a static method always belongs to the declaring class. */
747 :
748 37 : if (m->flags & ACC_STATIC) {
749 : /* For static methods we reset the object. */
750 :
751 7 : if (o != NULL)
752 0 : o = NULL;
753 :
754 : /* for convenience */
755 :
756 7 : resm = m;
757 :
758 : } else {
759 : /* For instance methods we make a virtual function table lookup. */
760 :
761 30 : resm = method_vftbl_lookup(vftbl, m);
762 : }
763 :
764 : STATISTICS(jnicallXmethodnvokation());
765 :
766 37 : (void) vm_call_method_valist(resm, o, ap);
767 : }
768 :
769 :
770 : /* _Jv_jni_CallVoidMethodA *****************************************************
771 :
772 : Internal function to call Java void methods.
773 :
774 : *******************************************************************************/
775 :
776 0 : static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
777 : methodinfo *m, const jvalue *args)
778 : {
779 : methodinfo *resm;
780 :
781 0 : if (m == NULL) {
782 0 : exceptions_throw_nullpointerexception();
783 0 : return;
784 : }
785 :
786 : /* Class initialization is done by the JIT compiler. This is ok
787 : since a static method always belongs to the declaring class. */
788 :
789 0 : if (m->flags & ACC_STATIC) {
790 : /* For static methods we reset the object. */
791 :
792 0 : if (o != NULL)
793 0 : o = NULL;
794 :
795 : /* for convenience */
796 :
797 0 : resm = m;
798 :
799 : } else {
800 : /* For instance methods we make a virtual function table lookup. */
801 :
802 0 : resm = method_vftbl_lookup(vftbl, m);
803 : }
804 :
805 : STATISTICS(jnicallXmethodnvokation());
806 :
807 0 : (void) vm_call_method_jvalue(resm, o, args);
808 : }
809 :
810 :
811 : // JNI functions are exported as C functions.
812 : extern "C" {
813 :
814 : /* GetVersion ******************************************************************
815 :
816 : Returns the major version number in the higher 16 bits and the
817 : minor version number in the lower 16 bits.
818 :
819 : *******************************************************************************/
820 :
821 0 : jint _Jv_JNI_GetVersion(JNIEnv *env)
822 : {
823 0 : TRACEJNICALLS(("_Jv_JNI_GetVersion(env=%p)", env));
824 :
825 0 : return JNI_VERSION_SUPPORTED;
826 : }
827 :
828 :
829 : /* Class Operations ***********************************************************/
830 :
831 : /* DefineClass *****************************************************************
832 :
833 : Loads a class from a buffer of raw class data. The buffer
834 : containing the raw class data is not referenced by the VM after the
835 : DefineClass call returns, and it may be discarded if desired.
836 :
837 : *******************************************************************************/
838 :
839 0 : jclass jni_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize bufLen)
840 : {
841 : #if defined(ENABLE_JAVASE)
842 0 : Utf8String u;
843 : classloader_t *cl;
844 : classinfo *c;
845 : java_handle_t* h;
846 :
847 0 : TRACEJNICALLS(("jni_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen));
848 :
849 0 : u = Utf8String::from_utf8(name);
850 0 : cl = loader_hashtable_classloader_add((java_handle_t *) loader);
851 :
852 0 : c = class_define(u, cl, bufLen, (uint8_t *) buf, NULL);
853 :
854 0 : h = LLNI_classinfo_wrap(c);
855 :
856 0 : return (jclass) jni_NewLocalRef(env, (jobject) h);
857 : #else
858 : vm_abort("jni_DefineClass: Not implemented in this configuration");
859 :
860 : // Keep compiler happy.
861 :
862 : return 0;
863 : #endif
864 : }
865 :
866 :
867 : /* FindClass *******************************************************************
868 :
869 : This function loads a locally-defined class. It searches the
870 : directories and zip files specified by the CLASSPATH environment
871 : variable for the class with the specified name.
872 :
873 : *******************************************************************************/
874 :
875 740 : jclass jni_FindClass(JNIEnv *env, const char *name)
876 : {
877 : #if defined(ENABLE_JAVASE)
878 : classinfo* cc;
879 : classinfo* c;
880 : java_handle_t* h;
881 :
882 740 : TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
883 :
884 : /* FIXME If name is NULL we have a problem here. */
885 :
886 740 : Utf8String u = Utf8String::from_utf8_dot_to_slash(name);
887 :
888 : /* if ((u == NULL) || (int)strlen(name) > symbolOopDesc::max_length() ) { */
889 740 : if (u == NULL) {
890 0 : exceptions_throw_noclassdeffounderror(u);
891 0 : return NULL;
892 : }
893 :
894 : /* Check stacktrace for classloader, if one found use it,
895 : otherwise use the system classloader. */
896 :
897 : /* Quote from the JNI documentation:
898 :
899 : In the Java 2 Platform, FindClass locates the class loader
900 : associated with the current native method. If the native code
901 : belongs to a system class, no class loader will be
902 : involved. Otherwise, the proper class loader will be invoked to
903 : load and link the named class. When FindClass is called through
904 : the Invocation Interface, there is no current native method or
905 : its associated class loader. In that case, the result of
906 : ClassLoader.getBaseClassLoader is used." */
907 :
908 740 : cc = stacktrace_get_current_class();
909 :
910 740 : if (cc == NULL)
911 0 : c = load_class_from_sysloader(u);
912 : else {
913 740 : classloader_t *cl = cc->classloader;
914 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
915 : /* See jni_FindClass in Hotspot's src/share/vm/prims/jni.cpp */
916 : if (!cl && cc->name == utf8::java_lang_ClassLoader_NativeLibrary)
917 : {
918 : methodinfo *m = class_resolveclassmethod(
919 : cc,
920 : Utf8String::from_utf8("getFromClass"),
921 : Utf8String::from_utf8("()Ljava/lang/Class;"),
922 : NULL,
923 : true);
924 :
925 : java_handle_t *h;
926 : if (m)
927 : h = vm_call_method(m, NULL);
928 :
929 : if (m && exceptions_get_exception() == NULL)
930 : cl = ((classinfo *) LLNI_UNWRAP(h))->classloader;
931 : else
932 : return NULL;
933 : }
934 : #endif
935 740 : c = load_class_from_classloader(u, cl);
936 : }
937 :
938 740 : if (c == NULL) {
939 0 : resolve_handle_pending_exception(true);
940 0 : return NULL;
941 : }
942 :
943 740 : if (!link_class(c))
944 0 : return NULL;
945 :
946 740 : h = LLNI_classinfo_wrap(c);
947 :
948 740 : return (jclass) jni_NewLocalRef(env, (jobject) h);
949 :
950 : #elif defined(ENABLE_JAVAME_CLDC1_1)
951 : classinfo *c;
952 :
953 : TRACEJNICALLS(("jni_FindClass(env=%p, name=%s)", env, name));
954 :
955 : Utf8String u = Utf8String:from_utf8_dot_to_slash(name);
956 : c = load_class_bootstrap(u);
957 :
958 : if (c == NULL) {
959 : resolve_handle_pending_exception(true);
960 : return NULL;
961 : }
962 :
963 : if (!link_class(c))
964 : return NULL;
965 :
966 : return (jclass) jni_NewLocalRef(env, (jobject) c);
967 :
968 : #else
969 : vm_abort("jni_FindClass: not implemented in this configuration");
970 :
971 : /* keep compiler happy */
972 :
973 : return NULL;
974 : #endif
975 : }
976 :
977 :
978 : /* GetSuperclass ***************************************************************
979 :
980 : If clazz represents any class other than the class Object, then
981 : this function returns the object that represents the superclass of
982 : the class specified by clazz.
983 :
984 : *******************************************************************************/
985 :
986 0 : jclass jni_GetSuperclass(JNIEnv *env, jclass sub)
987 : {
988 : classinfo* c;
989 : classinfo* super;
990 :
991 0 : TRACEJNICALLS(("jni_GetSuperclass(env=%p, sub=%p)", env, sub));
992 :
993 0 : c = LLNI_classinfo_unwrap(sub);
994 :
995 0 : if (c == NULL)
996 0 : return NULL;
997 :
998 0 : super = class_get_superclass(c);
999 :
1000 0 : java_handle_t* h = LLNI_classinfo_wrap(super);
1001 :
1002 0 : return (jclass) jni_NewLocalRef(env, (jobject) h);
1003 : }
1004 :
1005 :
1006 : /* IsAssignableFrom ************************************************************
1007 :
1008 : Determines whether an object of sub can be safely cast to sup.
1009 :
1010 : *******************************************************************************/
1011 :
1012 3 : jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
1013 : {
1014 : classinfo *to;
1015 : classinfo *from;
1016 :
1017 3 : TRACEJNICALLS(("_Jv_JNI_IsAssignableFrom(env=%p, sub=%p, sup=%p)", env, sub, sup));
1018 :
1019 3 : to = (classinfo *) sup;
1020 3 : from = (classinfo *) sub;
1021 :
1022 3 : return class_is_assignable_from(to, from);
1023 : }
1024 :
1025 :
1026 : /* Throw ***********************************************************************
1027 :
1028 : Causes a java.lang.Throwable object to be thrown.
1029 :
1030 : *******************************************************************************/
1031 :
1032 0 : jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
1033 : {
1034 : java_handle_t *o;
1035 :
1036 : STATISTICS(jniinvokation());
1037 :
1038 0 : o = (java_handle_t *) obj;
1039 :
1040 0 : exceptions_set_exception(o);
1041 :
1042 0 : return JNI_OK;
1043 : }
1044 :
1045 :
1046 : /* ThrowNew ********************************************************************
1047 :
1048 : Constructs an exception object from the specified class with the
1049 : message specified by message and causes that exception to be
1050 : thrown.
1051 :
1052 : *******************************************************************************/
1053 :
1054 9 : jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
1055 : {
1056 : classinfo *c;
1057 : java_handle_t *o;
1058 : java_handle_t *s;
1059 :
1060 : STATISTICS(jniinvokation());
1061 :
1062 9 : c = LLNI_classinfo_unwrap(clazz);
1063 9 : if (msg == NULL)
1064 0 : msg = "";
1065 9 : s = JavaString::from_utf8(msg);
1066 :
1067 : /* instantiate exception object */
1068 :
1069 9 : o = native_new_and_init_string(c, s);
1070 :
1071 9 : if (o == NULL)
1072 0 : return -1;
1073 :
1074 9 : exceptions_set_exception(o);
1075 :
1076 9 : return 0;
1077 : }
1078 :
1079 :
1080 : /* ExceptionOccurred ***********************************************************
1081 :
1082 : Determines if an exception is being thrown. The exception stays
1083 : being thrown until either the native code calls ExceptionClear(),
1084 : or the Java code handles the exception.
1085 :
1086 : *******************************************************************************/
1087 :
1088 101 : jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
1089 : {
1090 : java_handle_t *o;
1091 :
1092 101 : TRACEJNICALLS(("_Jv_JNI_ExceptionOccurred(env=%p)", env));
1093 :
1094 101 : o = exceptions_get_exception();
1095 :
1096 101 : return (jthrowable) jni_NewLocalRef(env, (jthrowable) o);
1097 : }
1098 :
1099 :
1100 : /* ExceptionDescribe ***********************************************************
1101 :
1102 : Prints an exception and a backtrace of the stack to a system
1103 : error-reporting channel, such as stderr. This is a convenience
1104 : routine provided for debugging.
1105 :
1106 : *******************************************************************************/
1107 :
1108 0 : void jni_ExceptionDescribe(JNIEnv *env)
1109 : {
1110 0 : TRACEJNICALLS(("jni_ExceptionDescribe(env=%p)", env));
1111 :
1112 0 : exceptions_print_stacktrace();
1113 0 : }
1114 :
1115 :
1116 : /* ExceptionClear **************************************************************
1117 :
1118 : Clears any exception that is currently being thrown. If no
1119 : exception is currently being thrown, this routine has no effect.
1120 :
1121 : *******************************************************************************/
1122 :
1123 0 : void jni_ExceptionClear(JNIEnv *env)
1124 : {
1125 0 : TRACEJNICALLS(("jni_ExceptionClear(env=%p)", env));
1126 :
1127 0 : exceptions_clear_exception();
1128 0 : }
1129 :
1130 :
1131 : /* FatalError ******************************************************************
1132 :
1133 : Raises a fatal error and does not expect the VM to recover. This
1134 : function does not return.
1135 :
1136 : *******************************************************************************/
1137 :
1138 0 : void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
1139 : {
1140 : STATISTICS(jniinvokation());
1141 :
1142 : /* this seems to be the best way */
1143 :
1144 0 : vm_abort("JNI Fatal error: %s", msg);
1145 0 : }
1146 :
1147 :
1148 : /* PushLocalFrame **************************************************************
1149 :
1150 : Creates a new local reference frame, in which at least a given
1151 : number of local references can be created.
1152 :
1153 : *******************************************************************************/
1154 :
1155 1 : jint jni_PushLocalFrame(JNIEnv* env, jint capacity)
1156 : {
1157 1 : TRACEJNICALLS(("jni_PushLocalFrame(env=%p, capacity=%d)", env, capacity));
1158 :
1159 1 : if (capacity <= 0)
1160 0 : return -1;
1161 :
1162 : /* add new local reference frame to current table */
1163 :
1164 1 : if (!localref_frame_push(capacity))
1165 0 : return -1;
1166 :
1167 1 : return 0;
1168 : }
1169 :
1170 :
1171 : /* PopLocalFrame ***************************************************************
1172 :
1173 : Pops off the current local reference frame, frees all the local
1174 : references, and returns a local reference in the previous local
1175 : reference frame for the given result object.
1176 :
1177 : *******************************************************************************/
1178 :
1179 0 : jobject jni_PopLocalFrame(JNIEnv* env, jobject result)
1180 : {
1181 0 : TRACEJNICALLS(("jni_PopLocalFrame(env=%p, result=%p)", env, result));
1182 :
1183 : /* release all current local frames */
1184 :
1185 0 : localref_frame_pop_all();
1186 :
1187 : /* add local reference and return the value */
1188 :
1189 0 : return jni_NewLocalRef(env, result);
1190 : }
1191 :
1192 :
1193 : /* DeleteLocalRef **************************************************************
1194 :
1195 : Deletes the local reference pointed to by localRef.
1196 :
1197 : *******************************************************************************/
1198 :
1199 284644 : void jni_DeleteLocalRef(JNIEnv *env, jobject localRef)
1200 : {
1201 : java_handle_t *o;
1202 :
1203 284644 : TRACEJNICALLS(("jni_DeleteLocalRef(env=%p, ref=%p)", env, localRef));
1204 :
1205 284644 : o = (java_handle_t *) localRef;
1206 :
1207 284644 : if (o == NULL)
1208 0 : return;
1209 :
1210 : /* delete the reference */
1211 :
1212 284644 : localref_del(o);
1213 : }
1214 :
1215 :
1216 : /* IsSameObject ****************************************************************
1217 :
1218 : Tests whether two references refer to the same Java object.
1219 :
1220 : *******************************************************************************/
1221 :
1222 6 : jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
1223 : {
1224 : java_handle_t *o1;
1225 : java_handle_t *o2;
1226 : jboolean result;
1227 :
1228 : STATISTICS(jniinvokation());
1229 :
1230 6 : o1 = (java_handle_t *) ref1;
1231 6 : o2 = (java_handle_t *) ref2;
1232 :
1233 : LLNI_CRITICAL_START;
1234 :
1235 6 : if (LLNI_UNWRAP(o1) == LLNI_UNWRAP(o2))
1236 3 : result = JNI_TRUE;
1237 : else
1238 3 : result = JNI_FALSE;
1239 :
1240 : LLNI_CRITICAL_END;
1241 :
1242 6 : return result;
1243 : }
1244 :
1245 :
1246 : /* NewLocalRef *****************************************************************
1247 :
1248 : Creates a new local reference that refers to the same object as ref.
1249 :
1250 : *******************************************************************************/
1251 :
1252 595787 : jobject jni_NewLocalRef(JNIEnv *env, jobject ref)
1253 : {
1254 : java_handle_t *o;
1255 : java_handle_t *localref;
1256 :
1257 595787 : TRACEJNICALLS(("jni_NewLocalRef(env=%p, ref=%p)", env, ref));
1258 :
1259 595787 : o = (java_handle_t *) ref;
1260 :
1261 595787 : if (o == NULL)
1262 101 : return NULL;
1263 :
1264 : /* insert the reference */
1265 :
1266 595686 : localref = localref_add(LLNI_DIRECT(o));
1267 :
1268 595686 : return (jobject) localref;
1269 : }
1270 :
1271 :
1272 : /* EnsureLocalCapacity *********************************************************
1273 :
1274 : Ensures that at least a given number of local references can be
1275 : created in the current thread
1276 :
1277 : *******************************************************************************/
1278 :
1279 0 : jint jni_EnsureLocalCapacity(JNIEnv* env, jint capacity)
1280 : {
1281 : localref_table *lrt;
1282 :
1283 0 : TRACEJNICALLS(("jni_EnsureLocalCapacity(env=%p, capacity=%d)", env, capacity));
1284 :
1285 : /* get local reference table (thread specific) */
1286 :
1287 0 : lrt = THREADOBJECT->_localref_table;
1288 :
1289 : /* check if capacity elements are available in the local references table */
1290 :
1291 0 : if ((lrt->used + capacity) > lrt->capacity)
1292 0 : return jni_PushLocalFrame(env, capacity);
1293 :
1294 0 : return 0;
1295 : }
1296 :
1297 :
1298 : /* AllocObject *****************************************************************
1299 :
1300 : Allocates a new Java object without invoking any of the
1301 : constructors for the object. Returns a reference to the object.
1302 :
1303 : *******************************************************************************/
1304 :
1305 0 : jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
1306 : {
1307 : classinfo *c;
1308 : java_handle_t *o;
1309 :
1310 : STATISTICS(jniinvokation());
1311 :
1312 0 : c = LLNI_classinfo_unwrap(clazz);
1313 :
1314 0 : if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
1315 0 : exceptions_throw_instantiationexception(c);
1316 0 : return NULL;
1317 : }
1318 :
1319 0 : o = builtin_new(c);
1320 :
1321 0 : return jni_NewLocalRef(env, (jobject) o);
1322 : }
1323 :
1324 :
1325 : /* NewObject *******************************************************************
1326 :
1327 : Programmers place all arguments that are to be passed to the
1328 : constructor immediately following the methodID
1329 : argument. NewObject() accepts these arguments and passes them to
1330 : the Java method that the programmer wishes to invoke.
1331 :
1332 : *******************************************************************************/
1333 :
1334 27 : jobject jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
1335 : {
1336 : java_handle_t *o;
1337 : classinfo *c;
1338 : methodinfo *m;
1339 : va_list ap;
1340 :
1341 27 : TRACEJNICALLSENTER(("jni_NewObject(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
1342 :
1343 27 : c = LLNI_classinfo_unwrap(clazz);
1344 27 : m = (methodinfo *) methodID;
1345 :
1346 : /* create object */
1347 :
1348 27 : o = builtin_new(c);
1349 :
1350 27 : if (o == NULL)
1351 0 : return NULL;
1352 :
1353 : /* call constructor */
1354 :
1355 27 : va_start(ap, methodID);
1356 27 : _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1357 27 : va_end(ap);
1358 :
1359 27 : TRACEJNICALLSEXIT(("->%p", o));
1360 :
1361 27 : return jni_NewLocalRef(env, (jobject) o);
1362 : }
1363 :
1364 :
1365 : /* NewObjectV ******************************************************************
1366 :
1367 : Programmers place all arguments that are to be passed to the
1368 : constructor in an args argument of type va_list that immediately
1369 : follows the methodID argument. NewObjectV() accepts these
1370 : arguments, and, in turn, passes them to the Java method that the
1371 : programmer wishes to invoke.
1372 :
1373 : *******************************************************************************/
1374 :
1375 0 : jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1376 : va_list args)
1377 : {
1378 : java_handle_t *o;
1379 : classinfo *c;
1380 : methodinfo *m;
1381 :
1382 : STATISTICS(jniinvokation());
1383 :
1384 0 : c = LLNI_classinfo_unwrap(clazz);
1385 0 : m = (methodinfo *) methodID;
1386 :
1387 : /* create object */
1388 :
1389 0 : o = builtin_new(c);
1390 :
1391 0 : if (o == NULL)
1392 0 : return NULL;
1393 :
1394 : /* call constructor */
1395 :
1396 0 : _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1397 :
1398 0 : return jni_NewLocalRef(env, (jobject) o);
1399 : }
1400 :
1401 :
1402 : /* NewObjectA *****************************************************************
1403 :
1404 : Programmers place all arguments that are to be passed to the
1405 : constructor in an args array of jvalues that immediately follows
1406 : the methodID argument. NewObjectA() accepts the arguments in this
1407 : array, and, in turn, passes them to the Java method that the
1408 : programmer wishes to invoke.
1409 :
1410 : *******************************************************************************/
1411 :
1412 0 : jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1413 : const jvalue *args)
1414 : {
1415 : java_handle_t *o;
1416 : classinfo *c;
1417 : methodinfo *m;
1418 :
1419 : STATISTICS(jniinvokation());
1420 :
1421 0 : c = LLNI_classinfo_unwrap(clazz);
1422 0 : m = (methodinfo *) methodID;
1423 :
1424 : /* create object */
1425 :
1426 0 : o = builtin_new(c);
1427 :
1428 0 : if (o == NULL)
1429 0 : return NULL;
1430 :
1431 : /* call constructor */
1432 :
1433 0 : _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1434 :
1435 0 : return jni_NewLocalRef(env, (jobject) o);
1436 : }
1437 :
1438 :
1439 : /* GetObjectClass **************************************************************
1440 :
1441 : Returns the class of an object.
1442 :
1443 : *******************************************************************************/
1444 :
1445 7 : jclass jni_GetObjectClass(JNIEnv *env, jobject obj)
1446 : {
1447 : java_handle_t* o;
1448 : classinfo* c;
1449 :
1450 7 : TRACEJNICALLS(("jni_GetObjectClass(env=%p, obj=%p)", env, obj));
1451 :
1452 7 : o = (java_handle_t *) obj;
1453 :
1454 7 : LLNI_class_get(o, c);
1455 :
1456 7 : java_handle_t* h = LLNI_classinfo_wrap(c);
1457 :
1458 7 : return (jclass) jni_NewLocalRef(env, (jobject) h);
1459 : }
1460 :
1461 :
1462 : /* IsInstanceOf ****************************************************************
1463 :
1464 : Tests whether an object is an instance of a class.
1465 :
1466 : *******************************************************************************/
1467 :
1468 3 : jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
1469 : {
1470 : classinfo *c;
1471 : java_handle_t *h;
1472 :
1473 3 : TRACEJNICALLS(("_Jv_JNI_IsInstanceOf(env=%p, obj=%p, clazz=%p)", env, obj, clazz));
1474 :
1475 : /* XXX Is this correct? */
1476 3 : c = LLNI_classinfo_unwrap(clazz);
1477 3 : h = (java_handle_t *) obj;
1478 :
1479 3 : return class_is_instance(c, h);
1480 : }
1481 :
1482 :
1483 : /* Reflection Support *********************************************************/
1484 :
1485 : /* FromReflectedMethod *********************************************************
1486 :
1487 : Converts java.lang.reflect.Method or java.lang.reflect.Constructor
1488 : object to a method ID.
1489 :
1490 : *******************************************************************************/
1491 :
1492 0 : jmethodID jni_FromReflectedMethod(JNIEnv *env, jobject method)
1493 : {
1494 : #if defined(ENABLE_JAVASE)
1495 : methodinfo* m;
1496 :
1497 0 : TRACEJNICALLS(("jni_FromReflectedMethod(env=%p, method=%p)", env, method));
1498 :
1499 0 : java_lang_Object o(method);
1500 :
1501 0 : if (o.is_null())
1502 0 : return NULL;
1503 :
1504 0 : if (o.get_Class() == class_java_lang_reflect_Constructor) {
1505 0 : java_lang_reflect_Constructor rc(method);
1506 0 : m = rc.get_method();
1507 : }
1508 : else {
1509 0 : assert(o.get_Class() == class_java_lang_reflect_Method);
1510 :
1511 0 : java_lang_reflect_Method rm(method);
1512 0 : m = rm.get_method();
1513 : }
1514 :
1515 0 : return (jmethodID) m;
1516 : #else
1517 : vm_abort("jni_FromReflectedMethod: Not implemented in this configuration.");
1518 :
1519 : // Keep compiler happy.
1520 : return NULL;
1521 : #endif
1522 : }
1523 :
1524 :
1525 : /* FromReflectedField **********************************************************
1526 :
1527 : Converts a java.lang.reflect.Field to a field ID.
1528 :
1529 : *******************************************************************************/
1530 :
1531 0 : jfieldID jni_FromReflectedField(JNIEnv* env, jobject field)
1532 : {
1533 : #if defined(ENABLE_JAVASE)
1534 :
1535 0 : TRACEJNICALLS(("jni_FromReflectedField(env=%p, field=%p)", env, field));
1536 :
1537 0 : java_lang_reflect_Field rf(field);
1538 :
1539 0 : if (rf.is_null())
1540 0 : return NULL;
1541 :
1542 0 : fieldinfo* f = rf.get_field();
1543 :
1544 0 : return (jfieldID) f;
1545 : #else
1546 : vm_abort("jni_FromReflectedField: Not implemented in this configuration.");
1547 :
1548 : // Keep compiler happy.
1549 : return NULL;
1550 : #endif
1551 : }
1552 :
1553 :
1554 : /* ToReflectedMethod ***********************************************************
1555 :
1556 : Converts a method ID derived from cls to an instance of the
1557 : java.lang.reflect.Method class or to an instance of the
1558 : java.lang.reflect.Constructor class.
1559 :
1560 : *******************************************************************************/
1561 :
1562 0 : jobject jni_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
1563 : {
1564 : #if defined(ENABLE_JAVASE)
1565 0 : TRACEJNICALLS(("jni_ToReflectedMethod(env=%p, cls=%p, methodID=%p, isStatic=%d)", env, cls, methodID, isStatic));
1566 :
1567 0 : methodinfo* m = (methodinfo *) methodID;
1568 :
1569 : /* HotSpot does the same assert. */
1570 :
1571 0 : assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
1572 :
1573 : java_handle_t* h;
1574 :
1575 0 : if (m->name == utf8::init) {
1576 0 : h = java_lang_reflect_Constructor(m).get_handle();
1577 : }
1578 : else {
1579 0 : h = java_lang_reflect_Method(m).get_handle();
1580 : }
1581 :
1582 0 : return (jobject) h;
1583 : #else
1584 : vm_abort("jni_ToReflectedMethod: Not implemented in this configuration.");
1585 :
1586 : /* keep compiler happy */
1587 :
1588 : return NULL;
1589 : #endif
1590 : }
1591 :
1592 :
1593 : /* ToReflectedField ************************************************************
1594 :
1595 : Converts a field ID derived from cls to an instance of the
1596 : java.lang.reflect.Field class.
1597 :
1598 : *******************************************************************************/
1599 :
1600 0 : jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1601 : jboolean isStatic)
1602 : {
1603 : STATISTICS(jniinvokation());
1604 :
1605 0 : log_text("JNI-Call: ToReflectedField: IMPLEMENT ME!");
1606 :
1607 0 : return NULL;
1608 : }
1609 :
1610 :
1611 : /* Calling Instance Methods ***************************************************/
1612 :
1613 : /* GetMethodID *****************************************************************
1614 :
1615 : Returns the method ID for an instance (nonstatic) method of a class
1616 : or interface. The method may be defined in one of the clazz's
1617 : superclasses and inherited by clazz. The method is determined by
1618 : its name and signature.
1619 :
1620 : GetMethodID() causes an uninitialized class to be initialized.
1621 :
1622 : *******************************************************************************/
1623 :
1624 1428 : jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
1625 : const char *sig)
1626 : {
1627 : classinfo *c;
1628 : methodinfo *m;
1629 :
1630 : STATISTICS(jniinvokation());
1631 :
1632 1428 : c = LLNI_classinfo_unwrap(clazz);
1633 :
1634 1428 : if (c == NULL)
1635 0 : return NULL;
1636 :
1637 1428 : if (!(c->state & CLASS_INITIALIZED))
1638 423 : if (!initialize_class(c))
1639 0 : return NULL;
1640 :
1641 : /* try to get the method of the class or one of it's superclasses */
1642 :
1643 1428 : Utf8String uname = Utf8String::from_utf8(name);
1644 1428 : Utf8String udesc = Utf8String::from_utf8(sig);
1645 :
1646 1428 : m = class_resolvemethod(c, uname, udesc);
1647 :
1648 1428 : if ((m == NULL) || (m->flags & ACC_STATIC)) {
1649 0 : exceptions_throw_nosuchmethoderror(c, uname, udesc);
1650 :
1651 0 : return NULL;
1652 : }
1653 :
1654 1428 : return (jmethodID) m;
1655 : }
1656 :
1657 :
1658 : /* JNI-functions for calling instance methods *********************************/
1659 :
1660 : #define JNI_CALL_VIRTUAL_METHOD(name, type, intern) \
1661 : type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj, \
1662 : jmethodID methodID, ...) \
1663 : { \
1664 : java_handle_t *o; \
1665 : methodinfo *m; \
1666 : va_list ap; \
1667 : type ret; \
1668 : \
1669 : o = (java_handle_t *) obj; \
1670 : m = (methodinfo *) methodID; \
1671 : \
1672 : va_start(ap, methodID); \
1673 : ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, ap); \
1674 : va_end(ap); \
1675 : \
1676 : return ret; \
1677 : }
1678 :
1679 94906 : JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
1680 0 : JNI_CALL_VIRTUAL_METHOD(Byte, jbyte, Int)
1681 0 : JNI_CALL_VIRTUAL_METHOD(Char, jchar, Int)
1682 0 : JNI_CALL_VIRTUAL_METHOD(Short, jshort, Int)
1683 284718 : JNI_CALL_VIRTUAL_METHOD(Int, jint, Int)
1684 0 : JNI_CALL_VIRTUAL_METHOD(Long, jlong, Long)
1685 0 : JNI_CALL_VIRTUAL_METHOD(Float, jfloat, Float)
1686 0 : JNI_CALL_VIRTUAL_METHOD(Double, jdouble, Double)
1687 :
1688 :
1689 : #define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern) \
1690 : type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj, \
1691 : jmethodID methodID, va_list args) \
1692 : { \
1693 : java_handle_t *o; \
1694 : methodinfo *m; \
1695 : type ret; \
1696 : \
1697 : o = (java_handle_t *) obj; \
1698 : m = (methodinfo *) methodID; \
1699 : \
1700 : ret = _Jv_jni_Call##intern##Method(o, LLNI_vftbl_direct(o), m, args); \
1701 : \
1702 : return ret; \
1703 : }
1704 :
1705 0 : JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
1706 0 : JNI_CALL_VIRTUAL_METHOD_V(Byte, jbyte, Int)
1707 0 : JNI_CALL_VIRTUAL_METHOD_V(Char, jchar, Int)
1708 0 : JNI_CALL_VIRTUAL_METHOD_V(Short, jshort, Int)
1709 0 : JNI_CALL_VIRTUAL_METHOD_V(Int, jint, Int)
1710 0 : JNI_CALL_VIRTUAL_METHOD_V(Long, jlong, Long)
1711 0 : JNI_CALL_VIRTUAL_METHOD_V(Float, jfloat, Float)
1712 0 : JNI_CALL_VIRTUAL_METHOD_V(Double, jdouble, Double)
1713 :
1714 :
1715 : #define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern) \
1716 : type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj, \
1717 : jmethodID methodID, \
1718 : const jvalue *args) \
1719 : { \
1720 : java_handle_t *o; \
1721 : methodinfo *m; \
1722 : type ret; \
1723 : \
1724 : o = (java_handle_t *) obj; \
1725 : m = (methodinfo *) methodID; \
1726 : \
1727 : ret = _Jv_jni_Call##intern##MethodA(o, LLNI_vftbl_direct(o), m, args); \
1728 : \
1729 : return ret; \
1730 : }
1731 :
1732 0 : JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
1733 0 : JNI_CALL_VIRTUAL_METHOD_A(Byte, jbyte, Int)
1734 0 : JNI_CALL_VIRTUAL_METHOD_A(Char, jchar, Int)
1735 0 : JNI_CALL_VIRTUAL_METHOD_A(Short, jshort, Int)
1736 0 : JNI_CALL_VIRTUAL_METHOD_A(Int, jint, Int)
1737 0 : JNI_CALL_VIRTUAL_METHOD_A(Long, jlong, Long)
1738 0 : JNI_CALL_VIRTUAL_METHOD_A(Float, jfloat, Float)
1739 0 : JNI_CALL_VIRTUAL_METHOD_A(Double, jdouble, Double)
1740 :
1741 :
1742 284620 : jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
1743 : ...)
1744 : {
1745 : java_handle_t *o;
1746 : methodinfo *m;
1747 : java_handle_t *ret;
1748 : va_list ap;
1749 :
1750 284620 : o = (java_handle_t *) obj;
1751 284620 : m = (methodinfo *) methodID;
1752 :
1753 284620 : va_start(ap, methodID);
1754 284620 : ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, ap);
1755 284620 : va_end(ap);
1756 :
1757 284620 : return jni_NewLocalRef(env, (jobject) ret);
1758 : }
1759 :
1760 :
1761 0 : jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1762 : va_list args)
1763 : {
1764 : java_handle_t *o;
1765 : methodinfo *m;
1766 : java_handle_t *ret;
1767 :
1768 0 : o = (java_handle_t *) obj;
1769 0 : m = (methodinfo *) methodID;
1770 :
1771 0 : ret = _Jv_jni_CallObjectMethod(o, LLNI_vftbl_direct(o), m, args);
1772 :
1773 0 : return jni_NewLocalRef(env, (jobject) ret);
1774 : }
1775 :
1776 :
1777 0 : jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1778 : const jvalue *args)
1779 : {
1780 : java_handle_t *o;
1781 : methodinfo *m;
1782 : java_handle_t *ret;
1783 :
1784 0 : o = (java_handle_t *) obj;
1785 0 : m = (methodinfo *) methodID;
1786 :
1787 0 : ret = _Jv_jni_CallObjectMethodA(o, LLNI_vftbl_direct(o), m, args);
1788 :
1789 0 : return jni_NewLocalRef(env, (jobject) ret);
1790 : }
1791 :
1792 :
1793 :
1794 3 : void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
1795 : {
1796 : java_handle_t *o;
1797 : methodinfo *m;
1798 : va_list ap;
1799 :
1800 3 : o = (java_handle_t *) obj;
1801 3 : m = (methodinfo *) methodID;
1802 :
1803 3 : va_start(ap, methodID);
1804 3 : _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, ap);
1805 3 : va_end(ap);
1806 3 : }
1807 :
1808 :
1809 0 : void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
1810 : va_list args)
1811 : {
1812 : java_handle_t *o;
1813 : methodinfo *m;
1814 :
1815 0 : o = (java_handle_t *) obj;
1816 0 : m = (methodinfo *) methodID;
1817 :
1818 0 : _Jv_jni_CallVoidMethod(o, LLNI_vftbl_direct(o), m, args);
1819 0 : }
1820 :
1821 :
1822 0 : void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
1823 : const jvalue *args)
1824 : {
1825 : java_handle_t *o;
1826 : methodinfo *m;
1827 :
1828 0 : o = (java_handle_t *) obj;
1829 0 : m = (methodinfo *) methodID;
1830 :
1831 0 : _Jv_jni_CallVoidMethodA(o, LLNI_vftbl_direct(o), m, args);
1832 0 : }
1833 :
1834 :
1835 :
1836 : #define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern) \
1837 : type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj, \
1838 : jclass clazz, jmethodID methodID, \
1839 : ...) \
1840 : { \
1841 : java_handle_t *o; \
1842 : classinfo *c; \
1843 : methodinfo *m; \
1844 : va_list ap; \
1845 : type ret; \
1846 : \
1847 : o = (java_handle_t *) obj; \
1848 : c = LLNI_classinfo_unwrap(clazz); \
1849 : m = (methodinfo *) methodID; \
1850 : \
1851 : va_start(ap, methodID); \
1852 : ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap); \
1853 : va_end(ap); \
1854 : \
1855 : return ret; \
1856 : }
1857 :
1858 0 : JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
1859 0 : JNI_CALL_NONVIRTUAL_METHOD(Byte, jbyte, Int)
1860 0 : JNI_CALL_NONVIRTUAL_METHOD(Char, jchar, Int)
1861 0 : JNI_CALL_NONVIRTUAL_METHOD(Short, jshort, Int)
1862 0 : JNI_CALL_NONVIRTUAL_METHOD(Int, jint, Int)
1863 0 : JNI_CALL_NONVIRTUAL_METHOD(Long, jlong, Long)
1864 0 : JNI_CALL_NONVIRTUAL_METHOD(Float, jfloat, Float)
1865 0 : JNI_CALL_NONVIRTUAL_METHOD(Double, jdouble, Double)
1866 :
1867 :
1868 : #define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern) \
1869 : type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj, \
1870 : jclass clazz, jmethodID methodID, \
1871 : va_list args) \
1872 : { \
1873 : java_handle_t *o; \
1874 : classinfo *c; \
1875 : methodinfo *m; \
1876 : type ret; \
1877 : \
1878 : o = (java_handle_t *) obj; \
1879 : c = LLNI_classinfo_unwrap(clazz); \
1880 : m = (methodinfo *) methodID; \
1881 : \
1882 : ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args); \
1883 : \
1884 : return ret; \
1885 : }
1886 :
1887 0 : JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
1888 0 : JNI_CALL_NONVIRTUAL_METHOD_V(Byte, jbyte, Int)
1889 0 : JNI_CALL_NONVIRTUAL_METHOD_V(Char, jchar, Int)
1890 0 : JNI_CALL_NONVIRTUAL_METHOD_V(Short, jshort, Int)
1891 0 : JNI_CALL_NONVIRTUAL_METHOD_V(Int, jint, Int)
1892 0 : JNI_CALL_NONVIRTUAL_METHOD_V(Long, jlong, Long)
1893 0 : JNI_CALL_NONVIRTUAL_METHOD_V(Float, jfloat, Float)
1894 0 : JNI_CALL_NONVIRTUAL_METHOD_V(Double, jdouble, Double)
1895 :
1896 :
1897 : #define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern) \
1898 : type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj, \
1899 : jclass clazz, jmethodID methodID, \
1900 : const jvalue *args) \
1901 : { \
1902 : log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!"); \
1903 : \
1904 : return 0; \
1905 : }
1906 :
1907 0 : JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
1908 0 : JNI_CALL_NONVIRTUAL_METHOD_A(Byte, jbyte, Int)
1909 0 : JNI_CALL_NONVIRTUAL_METHOD_A(Char, jchar, Int)
1910 0 : JNI_CALL_NONVIRTUAL_METHOD_A(Short, jshort, Int)
1911 0 : JNI_CALL_NONVIRTUAL_METHOD_A(Int, jint, Int)
1912 0 : JNI_CALL_NONVIRTUAL_METHOD_A(Long, jlong, Long)
1913 0 : JNI_CALL_NONVIRTUAL_METHOD_A(Float, jfloat, Float)
1914 0 : JNI_CALL_NONVIRTUAL_METHOD_A(Double, jdouble, Double)
1915 :
1916 0 : jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
1917 : jclass clazz, jmethodID methodID,
1918 : ...)
1919 : {
1920 : java_handle_t *o;
1921 : classinfo *c;
1922 : methodinfo *m;
1923 : java_handle_t *r;
1924 : va_list ap;
1925 :
1926 0 : o = (java_handle_t *) obj;
1927 0 : c = LLNI_classinfo_unwrap(clazz);
1928 0 : m = (methodinfo *) methodID;
1929 :
1930 0 : va_start(ap, methodID);
1931 0 : r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
1932 0 : va_end(ap);
1933 :
1934 0 : return jni_NewLocalRef(env, (jobject) r);
1935 : }
1936 :
1937 :
1938 0 : jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
1939 : jclass clazz, jmethodID methodID,
1940 : va_list args)
1941 : {
1942 : java_handle_t *o;
1943 : classinfo *c;
1944 : methodinfo *m;
1945 : java_handle_t *r;
1946 :
1947 0 : o = (java_handle_t *) obj;
1948 0 : c = LLNI_classinfo_unwrap(clazz);
1949 0 : m = (methodinfo *) methodID;
1950 :
1951 0 : r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
1952 :
1953 0 : return jni_NewLocalRef(env, (jobject) r);
1954 : }
1955 :
1956 :
1957 0 : jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
1958 : jclass clazz, jmethodID methodID,
1959 : const jvalue *args)
1960 : {
1961 0 : log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
1962 :
1963 0 : return jni_NewLocalRef(env, NULL);
1964 : }
1965 :
1966 :
1967 0 : void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
1968 : jmethodID methodID, ...)
1969 : {
1970 : java_handle_t *o;
1971 : classinfo *c;
1972 : methodinfo *m;
1973 : va_list ap;
1974 :
1975 0 : o = (java_handle_t *) obj;
1976 0 : c = LLNI_classinfo_unwrap(clazz);
1977 0 : m = (methodinfo *) methodID;
1978 :
1979 0 : va_start(ap, methodID);
1980 0 : _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
1981 0 : va_end(ap);
1982 0 : }
1983 :
1984 :
1985 0 : void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
1986 : jmethodID methodID, va_list args)
1987 : {
1988 : java_handle_t *o;
1989 : classinfo *c;
1990 : methodinfo *m;
1991 :
1992 0 : o = (java_handle_t *) obj;
1993 0 : c = LLNI_classinfo_unwrap(clazz);
1994 0 : m = (methodinfo *) methodID;
1995 :
1996 0 : _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
1997 0 : }
1998 :
1999 :
2000 0 : void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
2001 : jmethodID methodID, const jvalue * args)
2002 : {
2003 : java_handle_t *o;
2004 : classinfo *c;
2005 : methodinfo *m;
2006 :
2007 0 : o = (java_handle_t *) obj;
2008 0 : c = LLNI_classinfo_unwrap(clazz);
2009 0 : m = (methodinfo *) methodID;
2010 :
2011 0 : _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
2012 0 : }
2013 :
2014 :
2015 : /* Accessing Fields of Objects ************************************************/
2016 :
2017 : /* GetFieldID ******************************************************************
2018 :
2019 : Returns the field ID for an instance (nonstatic) field of a
2020 : class. The field is specified by its name and signature. The
2021 : Get<type>Field and Set<type>Field families of accessor functions
2022 : use field IDs to retrieve object fields.
2023 :
2024 : *******************************************************************************/
2025 :
2026 566 : jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
2027 : const char *sig)
2028 : {
2029 : classinfo *c;
2030 : fieldinfo *f;
2031 :
2032 : STATISTICS(jniinvokation());
2033 :
2034 566 : c = LLNI_classinfo_unwrap(clazz);
2035 :
2036 : /* XXX NPE check? */
2037 :
2038 566 : Utf8String uname = Utf8String::from_utf8(name);
2039 566 : Utf8String udesc = Utf8String::from_utf8(sig);
2040 :
2041 566 : f = class_findfield(c, uname, udesc);
2042 :
2043 566 : if (f == NULL)
2044 0 : exceptions_throw_nosuchfielderror(c, uname);
2045 :
2046 566 : return (jfieldID) f;
2047 : }
2048 :
2049 :
2050 : /* Get<type>Field Routines *****************************************************
2051 :
2052 : This family of accessor routines returns the value of an instance
2053 : (nonstatic) field of an object. The field to access is specified by
2054 : a field ID obtained by calling GetFieldID().
2055 :
2056 : *******************************************************************************/
2057 :
2058 : #define GET_FIELD(o,type,f) \
2059 : *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
2060 :
2061 : #define JNI_GET_FIELD(name, type, intern) \
2062 : type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
2063 : { \
2064 : intern ret; \
2065 : \
2066 : TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "Field(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID)); \
2067 : \
2068 : LLNI_CRITICAL_START; \
2069 : \
2070 : ret = GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID); \
2071 : \
2072 : LLNI_CRITICAL_END; \
2073 : \
2074 : return (type) ret; \
2075 : }
2076 :
2077 0 : JNI_GET_FIELD(Boolean, jboolean, s4)
2078 0 : JNI_GET_FIELD(Byte, jbyte, s4)
2079 0 : JNI_GET_FIELD(Char, jchar, s4)
2080 0 : JNI_GET_FIELD(Short, jshort, s4)
2081 1 : JNI_GET_FIELD(Int, jint, s4)
2082 0 : JNI_GET_FIELD(Long, jlong, s8)
2083 0 : JNI_GET_FIELD(Float, jfloat, float)
2084 0 : JNI_GET_FIELD(Double, jdouble, double)
2085 :
2086 :
2087 1 : jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
2088 : {
2089 : java_handle_t *o;
2090 :
2091 1 : TRACEJNICALLS(("_Jv_JNI_GetObjectField(env=%p, obj=%p, fieldId=%p)", env, obj, fieldID));
2092 :
2093 : LLNI_CRITICAL_START;
2094 :
2095 1 : o = LLNI_WRAP(GET_FIELD(LLNI_DIRECT((java_handle_t *) obj), java_object_t*, fieldID));
2096 :
2097 : LLNI_CRITICAL_END;
2098 :
2099 1 : return jni_NewLocalRef(env, (jobject) o);
2100 : }
2101 :
2102 :
2103 : /* Set<type>Field Routines *****************************************************
2104 :
2105 : This family of accessor routines sets the value of an instance
2106 : (nonstatic) field of an object. The field to access is specified by
2107 : a field ID obtained by calling GetFieldID().
2108 :
2109 : *******************************************************************************/
2110 :
2111 : #define SET_FIELD(o,type,f,value) \
2112 : *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
2113 :
2114 : #define GET_FIELDINFO(f) ((fieldinfo*) (f))
2115 :
2116 : #define JNI_SET_FIELD(name, type, intern) \
2117 : void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
2118 : type value) \
2119 : { \
2120 : TRACEJNICALLS(("_Jv_JNI_Set" STR(name) "Field(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value)); \
2121 : \
2122 : LLNI_CRITICAL_START; \
2123 : \
2124 : SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
2125 : \
2126 : LLNI_CRITICAL_END; \
2127 : \
2128 : if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE) \
2129 : Atomic::memory_barrier(); \
2130 : }
2131 :
2132 0 : JNI_SET_FIELD(Boolean, jboolean, s4)
2133 0 : JNI_SET_FIELD(Byte, jbyte, s4)
2134 0 : JNI_SET_FIELD(Char, jchar, s4)
2135 0 : JNI_SET_FIELD(Short, jshort, s4)
2136 0 : JNI_SET_FIELD(Int, jint, s4)
2137 0 : JNI_SET_FIELD(Long, jlong, s8)
2138 0 : JNI_SET_FIELD(Float, jfloat, float)
2139 0 : JNI_SET_FIELD(Double, jdouble, double)
2140 :
2141 :
2142 0 : void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
2143 : jobject value)
2144 : {
2145 0 : TRACEJNICALLS(("_Jv_JNI_SetObjectField(env=%p, obj=%p, fieldId=%p, value=%p)", env, obj, fieldID, value));
2146 :
2147 : LLNI_CRITICAL_START;
2148 :
2149 0 : SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
2150 :
2151 : LLNI_CRITICAL_END;
2152 :
2153 0 : if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE)
2154 0 : Atomic::memory_barrier();
2155 0 : }
2156 :
2157 :
2158 : /* Calling Static Methods *****************************************************/
2159 :
2160 : /* GetStaticMethodID ***********************************************************
2161 :
2162 : Returns the method ID for a static method of a class. The method is
2163 : specified by its name and signature.
2164 :
2165 : GetStaticMethodID() causes an uninitialized class to be
2166 : initialized.
2167 :
2168 : *******************************************************************************/
2169 :
2170 159 : jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
2171 : const char *sig)
2172 : {
2173 : classinfo *c;
2174 : methodinfo *m;
2175 :
2176 159 : TRACEJNICALLS(("_Jv_JNI_GetStaticMethodID(env=%p, clazz=%p, name=%s, sig=%s)", env, clazz, name, sig));
2177 :
2178 159 : c = LLNI_classinfo_unwrap(clazz);
2179 :
2180 159 : if (c == NULL)
2181 0 : return NULL;
2182 :
2183 159 : if (!(c->state & CLASS_INITIALIZED))
2184 146 : if (!initialize_class(c))
2185 0 : return NULL;
2186 :
2187 : /* try to get the static method of the class */
2188 :
2189 159 : Utf8String uname = Utf8String::from_utf8(name);
2190 159 : Utf8String udesc = Utf8String::from_utf8(sig);
2191 :
2192 159 : m = class_resolvemethod(c, uname, udesc);
2193 :
2194 159 : if ((m == NULL) || !(m->flags & ACC_STATIC)) {
2195 0 : exceptions_throw_nosuchmethoderror(c, uname, udesc);
2196 :
2197 0 : return NULL;
2198 : }
2199 :
2200 159 : return (jmethodID) m;
2201 : }
2202 :
2203 :
2204 : #define JNI_CALL_STATIC_METHOD(name, type, intern) \
2205 : type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
2206 : jmethodID methodID, ...) \
2207 : { \
2208 : methodinfo *m; \
2209 : va_list ap; \
2210 : type res; \
2211 : \
2212 : m = (methodinfo *) methodID; \
2213 : \
2214 : va_start(ap, methodID); \
2215 : res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap); \
2216 : va_end(ap); \
2217 : \
2218 : return res; \
2219 : }
2220 :
2221 1601 : JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
2222 0 : JNI_CALL_STATIC_METHOD(Byte, jbyte, Int)
2223 0 : JNI_CALL_STATIC_METHOD(Char, jchar, Int)
2224 0 : JNI_CALL_STATIC_METHOD(Short, jshort, Int)
2225 0 : JNI_CALL_STATIC_METHOD(Int, jint, Int)
2226 0 : JNI_CALL_STATIC_METHOD(Long, jlong, Long)
2227 0 : JNI_CALL_STATIC_METHOD(Float, jfloat, Float)
2228 0 : JNI_CALL_STATIC_METHOD(Double, jdouble, Double)
2229 :
2230 :
2231 : #define JNI_CALL_STATIC_METHOD_V(name, type, intern) \
2232 : type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz, \
2233 : jmethodID methodID, va_list args) \
2234 : { \
2235 : methodinfo *m; \
2236 : type res; \
2237 : \
2238 : m = (methodinfo *) methodID; \
2239 : \
2240 : res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args); \
2241 : \
2242 : return res; \
2243 : }
2244 :
2245 0 : JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
2246 0 : JNI_CALL_STATIC_METHOD_V(Byte, jbyte, Int)
2247 0 : JNI_CALL_STATIC_METHOD_V(Char, jchar, Int)
2248 0 : JNI_CALL_STATIC_METHOD_V(Short, jshort, Int)
2249 0 : JNI_CALL_STATIC_METHOD_V(Int, jint, Int)
2250 0 : JNI_CALL_STATIC_METHOD_V(Long, jlong, Long)
2251 0 : JNI_CALL_STATIC_METHOD_V(Float, jfloat, Float)
2252 0 : JNI_CALL_STATIC_METHOD_V(Double, jdouble, Double)
2253 :
2254 :
2255 : #define JNI_CALL_STATIC_METHOD_A(name, type, intern) \
2256 : type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz, \
2257 : jmethodID methodID, const jvalue *args) \
2258 : { \
2259 : methodinfo *m; \
2260 : type res; \
2261 : \
2262 : m = (methodinfo *) methodID; \
2263 : \
2264 : res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args); \
2265 : \
2266 : return res; \
2267 : }
2268 :
2269 0 : JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
2270 0 : JNI_CALL_STATIC_METHOD_A(Byte, jbyte, Int)
2271 0 : JNI_CALL_STATIC_METHOD_A(Char, jchar, Int)
2272 0 : JNI_CALL_STATIC_METHOD_A(Short, jshort, Int)
2273 0 : JNI_CALL_STATIC_METHOD_A(Int, jint, Int)
2274 0 : JNI_CALL_STATIC_METHOD_A(Long, jlong, Long)
2275 0 : JNI_CALL_STATIC_METHOD_A(Float, jfloat, Float)
2276 0 : JNI_CALL_STATIC_METHOD_A(Double, jdouble, Double)
2277 :
2278 :
2279 0 : jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
2280 : jmethodID methodID, ...)
2281 : {
2282 : methodinfo *m;
2283 : java_handle_t *o;
2284 : va_list ap;
2285 :
2286 0 : TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2287 :
2288 0 : m = (methodinfo *) methodID;
2289 :
2290 0 : va_start(ap, methodID);
2291 0 : o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
2292 0 : va_end(ap);
2293 :
2294 0 : return jni_NewLocalRef(env, (jobject) o);
2295 : }
2296 :
2297 :
2298 0 : jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
2299 : jmethodID methodID, va_list args)
2300 : {
2301 : methodinfo *m;
2302 : java_handle_t *o;
2303 :
2304 0 : TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodV(env=%p, clazz=%p, methodID=%p)", env, clazz, methodID));
2305 :
2306 0 : m = (methodinfo *) methodID;
2307 :
2308 0 : o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
2309 :
2310 0 : return jni_NewLocalRef(env, (jobject) o);
2311 : }
2312 :
2313 :
2314 0 : jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
2315 : jmethodID methodID, const jvalue *args)
2316 : {
2317 : methodinfo *m;
2318 : java_handle_t *o;
2319 :
2320 0 : TRACEJNICALLS(("_Jv_JNI_CallStaticObjectMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2321 :
2322 0 : m = (methodinfo *) methodID;
2323 :
2324 0 : o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
2325 :
2326 0 : return jni_NewLocalRef(env, (jobject) o);
2327 : }
2328 :
2329 :
2330 0 : void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
2331 : jmethodID methodID, ...)
2332 : {
2333 : methodinfo *m;
2334 : va_list ap;
2335 :
2336 0 : TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethod(env=%p, clazz=%p, methodID=%p, ...)", env, clazz, methodID));
2337 :
2338 0 : m = (methodinfo *) methodID;
2339 :
2340 0 : va_start(ap, methodID);
2341 0 : _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
2342 0 : va_end(ap);
2343 0 : }
2344 :
2345 :
2346 7 : void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
2347 : jmethodID methodID, va_list args)
2348 : {
2349 : methodinfo *m;
2350 :
2351 7 : TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodV(env=%p, clazz=%p, methodID=%p)", env, clazz, methodID));
2352 :
2353 7 : m = (methodinfo *) methodID;
2354 :
2355 7 : _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
2356 7 : }
2357 :
2358 :
2359 0 : void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
2360 : jmethodID methodID, const jvalue * args)
2361 : {
2362 : methodinfo *m;
2363 :
2364 0 : TRACEJNICALLS(("_Jv_JNI_CallStaticVoidMethodA(env=%p, clazz=%p, methodID=%p, args=%p)", env, clazz, methodID, args));
2365 :
2366 0 : m = (methodinfo *) methodID;
2367 :
2368 0 : _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
2369 0 : }
2370 :
2371 :
2372 : /* Accessing Static Fields ****************************************************/
2373 :
2374 : /* GetStaticFieldID ************************************************************
2375 :
2376 : Returns the field ID for a static field of a class. The field is
2377 : specified by its name and signature. The GetStatic<type>Field and
2378 : SetStatic<type>Field families of accessor functions use field IDs
2379 : to retrieve static fields.
2380 :
2381 : *******************************************************************************/
2382 :
2383 42 : jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
2384 : const char *sig)
2385 : {
2386 : classinfo *c;
2387 : fieldinfo *f;
2388 :
2389 : STATISTICS(jniinvokation());
2390 :
2391 42 : c = LLNI_classinfo_unwrap(clazz);
2392 :
2393 42 : Utf8String uname = Utf8String::from_utf8(name);
2394 42 : Utf8String usig = Utf8String::from_utf8(sig);
2395 :
2396 42 : f = class_findfield(c, uname, usig);
2397 :
2398 42 : if (f == NULL)
2399 0 : exceptions_throw_nosuchfielderror(c, uname);
2400 :
2401 42 : return (jfieldID) f;
2402 : }
2403 :
2404 :
2405 : /* GetStatic<type>Field ********************************************************
2406 :
2407 : This family of accessor routines returns the value of a static
2408 : field of an object.
2409 :
2410 : *******************************************************************************/
2411 :
2412 : #define JNI_GET_STATIC_FIELD(name, type, field) \
2413 : type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
2414 : jfieldID fieldID) \
2415 : { \
2416 : classinfo *c; \
2417 : fieldinfo *f; \
2418 : \
2419 : STATISTICS(jniinvokation()); \
2420 : \
2421 : c = LLNI_classinfo_unwrap(clazz); \
2422 : f = (fieldinfo *) fieldID; \
2423 : \
2424 : if (!(c->state & CLASS_INITIALIZED)) \
2425 : if (!initialize_class(c)) \
2426 : return 0; \
2427 : \
2428 : return f->value->field; \
2429 : }
2430 :
2431 0 : JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
2432 0 : JNI_GET_STATIC_FIELD(Byte, jbyte, i)
2433 0 : JNI_GET_STATIC_FIELD(Char, jchar, i)
2434 0 : JNI_GET_STATIC_FIELD(Short, jshort, i)
2435 1 : JNI_GET_STATIC_FIELD(Int, jint, i)
2436 0 : JNI_GET_STATIC_FIELD(Long, jlong, l)
2437 0 : JNI_GET_STATIC_FIELD(Float, jfloat, f)
2438 33 : JNI_GET_STATIC_FIELD(Double, jdouble, d)
2439 :
2440 :
2441 1 : jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
2442 : jfieldID fieldID)
2443 : {
2444 : classinfo *c;
2445 : fieldinfo *f;
2446 : java_handle_t *h;
2447 :
2448 : STATISTICS(jniinvokation());
2449 :
2450 1 : c = LLNI_classinfo_unwrap(clazz);
2451 1 : f = (fieldinfo *) fieldID;
2452 :
2453 1 : if (!(c->state & CLASS_INITIALIZED))
2454 0 : if (!initialize_class(c))
2455 0 : return NULL;
2456 :
2457 1 : h = (java_handle_t*) LLNI_WRAP(f->value->a);
2458 :
2459 1 : return jni_NewLocalRef(env, (jobject) h);
2460 : }
2461 :
2462 :
2463 : /* SetStatic<type>Field *******************************************************
2464 :
2465 : This family of accessor routines sets the value of a static field
2466 : of an object.
2467 :
2468 : *******************************************************************************/
2469 :
2470 : #define JNI_SET_STATIC_FIELD(name, type, field) \
2471 : void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
2472 : jfieldID fieldID, \
2473 : type value) \
2474 : { \
2475 : classinfo *c; \
2476 : fieldinfo *f; \
2477 : \
2478 : STATISTICS(jniinvokation()); \
2479 : \
2480 : c = LLNI_classinfo_unwrap(clazz); \
2481 : f = (fieldinfo *) fieldID; \
2482 : \
2483 : if (!(c->state & CLASS_INITIALIZED)) \
2484 : if (!initialize_class(c)) \
2485 : return; \
2486 : \
2487 : f->value->field = value; \
2488 : \
2489 : if (f->flags & ACC_VOLATILE) \
2490 : Atomic::memory_barrier(); \
2491 : }
2492 :
2493 0 : JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
2494 0 : JNI_SET_STATIC_FIELD(Byte, jbyte, i)
2495 0 : JNI_SET_STATIC_FIELD(Char, jchar, i)
2496 0 : JNI_SET_STATIC_FIELD(Short, jshort, i)
2497 4 : JNI_SET_STATIC_FIELD(Int, jint, i)
2498 3 : JNI_SET_STATIC_FIELD(Long, jlong, l)
2499 0 : JNI_SET_STATIC_FIELD(Float, jfloat, f)
2500 0 : JNI_SET_STATIC_FIELD(Double, jdouble, d)
2501 :
2502 :
2503 0 : void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
2504 : jobject value)
2505 : {
2506 : classinfo *c;
2507 : fieldinfo *f;
2508 :
2509 : STATISTICS(jniinvokation());
2510 :
2511 0 : c = LLNI_classinfo_unwrap(clazz);
2512 0 : f = (fieldinfo *) fieldID;
2513 :
2514 0 : if (!(c->state & CLASS_INITIALIZED))
2515 0 : if (!initialize_class(c))
2516 0 : return;
2517 :
2518 0 : f->value->a = LLNI_UNWRAP((java_handle_t *) value);
2519 :
2520 0 : if (f->flags & ACC_VOLATILE)
2521 0 : Atomic::memory_barrier();
2522 : }
2523 :
2524 :
2525 : /* String Operations **********************************************************/
2526 :
2527 : /* NewString *******************************************************************
2528 :
2529 : Create new java.lang.String object from an array of Unicode
2530 : characters.
2531 :
2532 : *******************************************************************************/
2533 :
2534 0 : jstring jni_NewString(JNIEnv *env, const jchar *buf, jsize len)
2535 : {
2536 0 : TRACEJNICALLS(("jni_NewString(env=%p, buf=%p, len=%d)", env, buf, len));
2537 :
2538 0 : JavaString js = JavaString::from_utf16(buf, len);
2539 :
2540 0 : if (js == NULL)
2541 0 : return NULL;
2542 :
2543 0 : return (jstring) jni_NewLocalRef(env, (jobject) (java_handle_t*) js);
2544 : }
2545 :
2546 :
2547 : static jchar emptyStringJ[]={0,0};
2548 :
2549 : /* GetStringLength *************************************************************
2550 :
2551 : Returns the length (the count of Unicode characters) of a Java
2552 : string.
2553 :
2554 : *******************************************************************************/
2555 :
2556 0 : jsize jni_GetStringLength(JNIEnv *env, jstring str)
2557 : {
2558 0 : TRACEJNICALLSENTER(("jni_GetStringLength(env=%p, str=%p)", env, str));
2559 :
2560 0 : java_lang_String s(str);
2561 0 : jsize count = runtime_str_ops::get_string_count(s);
2562 :
2563 0 : TRACEJNICALLSEXIT(("->%d)", count));
2564 :
2565 0 : return count;
2566 : }
2567 :
2568 :
2569 : /* GetStringChars **************************************************************
2570 :
2571 : Returns a pointer to the array of Unicode characters of the
2572 : string. This pointer is valid until ReleaseStringChars() is called.
2573 :
2574 : *******************************************************************************/
2575 :
2576 0 : const jchar* jni_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
2577 : {
2578 : u2 *stringbuffer;
2579 : int32_t i;
2580 :
2581 0 : TRACEJNICALLS(("jni_GetStringChars(env=%p, str=%p, isCopy=%p)", env, str, isCopy));
2582 :
2583 0 : if (str == NULL)
2584 : // FIXME This is really ugly.
2585 0 : return emptyStringJ;
2586 :
2587 0 : java_lang_String s(str);
2588 :
2589 0 : CharArray ca(s.get_value());
2590 :
2591 0 : int32_t count = runtime_str_ops::get_string_count(s);
2592 0 : int32_t offset = runtime_str_ops::get_string_offset(s);
2593 :
2594 0 : if (ca.is_null())
2595 0 : return NULL;
2596 :
2597 : /* allocate memory */
2598 :
2599 0 : stringbuffer = MNEW(u2, count + 1);
2600 :
2601 : /* copy text */
2602 :
2603 : // XXX: Fix me!
2604 0 : uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
2605 0 : for (i = 0; i < count; i++)
2606 0 : stringbuffer[i] = ptr[offset + i];
2607 :
2608 : /* terminate string */
2609 :
2610 0 : stringbuffer[i] = '\0';
2611 :
2612 0 : if (isCopy)
2613 0 : *isCopy = JNI_TRUE;
2614 :
2615 0 : return (jchar*) stringbuffer;
2616 : }
2617 :
2618 :
2619 : /* ReleaseStringChars **********************************************************
2620 :
2621 : Informs the VM that the native code no longer needs access to
2622 : chars. The chars argument is a pointer obtained from string using
2623 : GetStringChars().
2624 :
2625 : *******************************************************************************/
2626 :
2627 0 : void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
2628 : {
2629 0 : TRACEJNICALLS(("jni_ReleaseStringChars(env=%p, str=%p, chars=%p)", env, str, chars));
2630 :
2631 : // FIXME
2632 0 : if (chars == emptyStringJ)
2633 0 : return;
2634 :
2635 0 : java_lang_String s(str);
2636 0 : int32_t count = runtime_str_ops::get_string_count(s);
2637 :
2638 0 : MFREE(((jchar*) chars), jchar, count + 1);
2639 : }
2640 :
2641 :
2642 : /* NewStringUTF ****************************************************************
2643 :
2644 : Constructs a new java.lang.String object from an array of UTF-8
2645 : characters.
2646 :
2647 : *******************************************************************************/
2648 :
2649 2126 : jstring jni_NewStringUTF(JNIEnv *env, const char *bytes)
2650 : {
2651 2126 : TRACEJNICALLS(("jni_NewStringUTF(env=%p, bytes=%s)", env, bytes));
2652 :
2653 2126 : java_handle_t *h = JavaString::from_utf8(bytes);
2654 :
2655 2126 : return (jstring) jni_NewLocalRef(env, (jobject) h);
2656 : }
2657 :
2658 :
2659 : /****************** returns the utf8 length in bytes of a string *******************/
2660 :
2661 0 : jsize jni_GetStringUTFLength(JNIEnv *env, jstring string)
2662 : {
2663 0 : TRACEJNICALLS(("jni_GetStringUTFLength(env=%p, string=%p)", env, string));
2664 :
2665 0 : return JavaString((java_handle_t*) string).utf8_size();
2666 : }
2667 :
2668 :
2669 : /* GetStringUTFChars ***********************************************************
2670 :
2671 : Returns a pointer to an array of UTF-8 characters of the
2672 : string. This array is valid until it is released by
2673 : ReleaseStringUTFChars().
2674 :
2675 : *******************************************************************************/
2676 :
2677 3032 : const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
2678 : jboolean *isCopy)
2679 : {
2680 : STATISTICS(jniinvokation());
2681 :
2682 3032 : if (string == NULL)
2683 0 : return "";
2684 :
2685 3032 : if (isCopy)
2686 2 : *isCopy = JNI_TRUE;
2687 :
2688 3032 : Utf8String u = JavaString((java_handle_t *) string).to_utf8();
2689 :
2690 3032 : if (u != NULL)
2691 3032 : return u.begin();
2692 :
2693 0 : return "";
2694 : }
2695 :
2696 :
2697 : /* ReleaseStringUTFChars *******************************************************
2698 :
2699 : Informs the VM that the native code no longer needs access to
2700 : utf. The utf argument is a pointer derived from string using
2701 : GetStringUTFChars().
2702 :
2703 : *******************************************************************************/
2704 :
2705 3032 : void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
2706 : {
2707 : STATISTICS(jniinvokation());
2708 :
2709 : /* XXX we don't release utf chars right now, perhaps that should be done
2710 : later. Since there is always one reference the garbage collector will
2711 : never get them */
2712 3032 : }
2713 :
2714 :
2715 : /* Array Operations ***********************************************************/
2716 :
2717 : /* GetArrayLength **************************************************************
2718 :
2719 : Returns the number of elements in the array.
2720 :
2721 : *******************************************************************************/
2722 :
2723 3 : jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
2724 : {
2725 3 : TRACEJNICALLS(("_Jv_JNI_GetArrayLength(env=%p, array=%p)", env, array));
2726 :
2727 3 : Array a(array);
2728 :
2729 3 : jsize size = a.get_length();
2730 :
2731 3 : return size;
2732 : }
2733 :
2734 :
2735 : /* NewObjectArray **************************************************************
2736 :
2737 : Constructs a new array holding objects in class elementClass. All
2738 : elements are initially set to initialElement.
2739 :
2740 : *******************************************************************************/
2741 :
2742 308151 : jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
2743 : jclass elementClass, jobject initialElement)
2744 : {
2745 : classinfo* c;
2746 : java_handle_t* o;
2747 : s4 i;
2748 :
2749 : STATISTICS(jniinvokation());
2750 :
2751 308151 : c = LLNI_classinfo_unwrap(elementClass);
2752 308151 : o = (java_handle_t *) initialElement;
2753 :
2754 308151 : if (length < 0) {
2755 0 : exceptions_throw_negativearraysizeexception();
2756 0 : return NULL;
2757 : }
2758 :
2759 308151 : ObjectArray oa(length, c);
2760 :
2761 308151 : if (oa.is_null())
2762 1 : return NULL;
2763 :
2764 : /* set all elements to initialElement */
2765 :
2766 7345320 : for (i = 0; i < length; i++)
2767 7037170 : oa.set_element(i, o);
2768 :
2769 308150 : return (jobjectArray) jni_NewLocalRef(env, (jobject) oa.get_handle());
2770 : }
2771 :
2772 :
2773 12 : jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
2774 : jsize index)
2775 : {
2776 : STATISTICS(jniinvokation());
2777 :
2778 12 : ObjectArray oa(array);
2779 :
2780 12 : if (index >= oa.get_length()) {
2781 0 : exceptions_throw_arrayindexoutofboundsexception();
2782 0 : return NULL;
2783 : }
2784 :
2785 12 : java_handle_t* o = oa.get_element(index);
2786 :
2787 12 : return jni_NewLocalRef(env, (jobject) o);
2788 : }
2789 :
2790 :
2791 0 : void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
2792 : jsize index, jobject val)
2793 : {
2794 : STATISTICS(jniinvokation());
2795 :
2796 0 : ObjectArray oa(array);
2797 :
2798 0 : if (index >= oa.get_length()) {
2799 0 : exceptions_throw_arrayindexoutofboundsexception();
2800 : return;
2801 : }
2802 :
2803 : /* check if the class of value is a subclass of the element class
2804 : of the array */
2805 :
2806 0 : java_handle_t* o = (java_handle_t *) val;
2807 :
2808 0 : if (!builtin_canstore(oa.get_handle(), o))
2809 : return;
2810 :
2811 0 : oa.set_element(index, o);
2812 : }
2813 :
2814 :
2815 : #define JNI_NEW_ARRAY(name, type) \
2816 : type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len) \
2817 : { \
2818 : STATISTICS(jniinvokation()); \
2819 : \
2820 : if (len < 0) { \
2821 : exceptions_throw_negativearraysizeexception(); \
2822 : return NULL; \
2823 : } \
2824 : \
2825 : name##Array a(len); \
2826 : \
2827 : return (type) jni_NewLocalRef(env, \
2828 : (jobject) a.get_handle()); \
2829 : }
2830 :
2831 0 : JNI_NEW_ARRAY(Boolean, jbooleanArray)
2832 0 : JNI_NEW_ARRAY(Byte, jbyteArray)
2833 0 : JNI_NEW_ARRAY(Char, jcharArray)
2834 0 : JNI_NEW_ARRAY(Short, jshortArray)
2835 1 : JNI_NEW_ARRAY(Int, jintArray)
2836 1 : JNI_NEW_ARRAY(Long, jlongArray)
2837 0 : JNI_NEW_ARRAY(Float, jfloatArray)
2838 0 : JNI_NEW_ARRAY(Double, jdoubleArray)
2839 :
2840 :
2841 : /* Get<PrimitiveType>ArrayElements *********************************************
2842 :
2843 : A family of functions that returns the body of the primitive array.
2844 :
2845 : *******************************************************************************/
2846 :
2847 : #define JNI_GET_ARRAY_ELEMENTS(name, type, intern) \
2848 : type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
2849 : jboolean *isCopy) \
2850 : { \
2851 : TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayElements(env=%p, array=%p, isCopy=%d)", env, array, isCopy)); \
2852 : \
2853 : name##Array a(array); \
2854 : \
2855 : if (isCopy) \
2856 : *isCopy = JNI_FALSE; \
2857 : \
2858 : return (type *) a.get_raw_data_ptr(); \
2859 : }
2860 :
2861 0 : JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
2862 94906 : JNI_GET_ARRAY_ELEMENTS(Byte, jbyte, byte)
2863 0 : JNI_GET_ARRAY_ELEMENTS(Char, jchar, char)
2864 0 : JNI_GET_ARRAY_ELEMENTS(Short, jshort, short)
2865 1 : JNI_GET_ARRAY_ELEMENTS(Int, jint, int)
2866 1 : JNI_GET_ARRAY_ELEMENTS(Long, jlong, long)
2867 0 : JNI_GET_ARRAY_ELEMENTS(Float, jfloat, float)
2868 0 : JNI_GET_ARRAY_ELEMENTS(Double, jdouble, double)
2869 :
2870 :
2871 : /* Release<PrimitiveType>ArrayElements *****************************************
2872 :
2873 : A family of functions that informs the VM that the native code no
2874 : longer needs access to elems. The elems argument is a pointer
2875 : derived from array using the corresponding
2876 : Get<PrimitiveType>ArrayElements() function. If necessary, this
2877 : function copies back all changes made to elems to the original
2878 : array.
2879 :
2880 : *******************************************************************************/
2881 :
2882 : #define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2) \
2883 : void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array, \
2884 : type *elems, jint mode) \
2885 : { \
2886 : STATISTICS(jniinvokation()); \
2887 : \
2888 : name##Array a(array); \
2889 : \
2890 : if (elems != (type *) a.get_raw_data_ptr()) { \
2891 : switch (mode) { \
2892 : case JNI_COMMIT: \
2893 : a.set_region(0, a.get_length(), (intern2 *) elems); \
2894 : break; \
2895 : case 0: \
2896 : a.set_region(0, a.get_length(), (intern2 *) elems); \
2897 : /* XXX TWISTI how should it be freed? */ \
2898 : break; \
2899 : case JNI_ABORT: \
2900 : /* XXX TWISTI how should it be freed? */ \
2901 : break; \
2902 : } \
2903 : } \
2904 : }
2905 :
2906 0 : JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
2907 94906 : JNI_RELEASE_ARRAY_ELEMENTS(Byte, jbyte, byte, s1)
2908 0 : JNI_RELEASE_ARRAY_ELEMENTS(Char, jchar, char, u2)
2909 0 : JNI_RELEASE_ARRAY_ELEMENTS(Short, jshort, short, s2)
2910 1 : JNI_RELEASE_ARRAY_ELEMENTS(Int, jint, int, s4)
2911 1 : JNI_RELEASE_ARRAY_ELEMENTS(Long, jlong, long, s8)
2912 0 : JNI_RELEASE_ARRAY_ELEMENTS(Float, jfloat, float, float)
2913 0 : JNI_RELEASE_ARRAY_ELEMENTS(Double, jdouble, double, double)
2914 :
2915 :
2916 : /* Get<PrimitiveType>ArrayRegion **********************************************
2917 :
2918 : A family of functions that copies a region of a primitive array
2919 : into a buffer.
2920 :
2921 : *******************************************************************************/
2922 :
2923 : #define JNI_GET_ARRAY_REGION(name, type, intern, intern2) \
2924 : void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array, \
2925 : jsize start, jsize len, type *buf) \
2926 : { \
2927 : TRACEJNICALLS(("_Jv_JNI_Get" STR(name) "ArrayRegion(env=%p, array=%p, start=%d, len=%d, buf=%p)", env, array, start, len, buf)); \
2928 : \
2929 : name##Array a(array); \
2930 : \
2931 : if ((start < 0) || (len < 0) || (start + len > a.get_length())) \
2932 : exceptions_throw_arrayindexoutofboundsexception(); \
2933 : else \
2934 : a.get_region(start, len, (intern2 *) buf); \
2935 : }
2936 :
2937 0 : JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2938 0 : JNI_GET_ARRAY_REGION(Byte, jbyte, byte, s1)
2939 0 : JNI_GET_ARRAY_REGION(Char, jchar, char, u2)
2940 0 : JNI_GET_ARRAY_REGION(Short, jshort, short, s2)
2941 0 : JNI_GET_ARRAY_REGION(Int, jint, int, s4)
2942 0 : JNI_GET_ARRAY_REGION(Long, jlong, long, s8)
2943 0 : JNI_GET_ARRAY_REGION(Float, jfloat, float, float)
2944 0 : JNI_GET_ARRAY_REGION(Double, jdouble, double, double)
2945 :
2946 :
2947 : /* Set<PrimitiveType>ArrayRegion **********************************************
2948 :
2949 : A family of functions that copies back a region of a primitive
2950 : array from a buffer.
2951 :
2952 : *******************************************************************************/
2953 :
2954 : #define JNI_SET_ARRAY_REGION(name, type, intern, intern2) \
2955 : void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array, \
2956 : jsize start, jsize len, const type *buf) \
2957 : { \
2958 : STATISTICS(jniinvokation()); \
2959 : \
2960 : name##Array a(array); \
2961 : \
2962 : if ((start < 0) || (len < 0) || (start + len > a.get_length())) \
2963 : exceptions_throw_arrayindexoutofboundsexception(); \
2964 : else \
2965 : a.set_region(start, len, (intern2 *) buf); \
2966 : }
2967 :
2968 0 : JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
2969 0 : JNI_SET_ARRAY_REGION(Byte, jbyte, byte, s1)
2970 0 : JNI_SET_ARRAY_REGION(Char, jchar, char, u2)
2971 0 : JNI_SET_ARRAY_REGION(Short, jshort, short, s2)
2972 0 : JNI_SET_ARRAY_REGION(Int, jint, int, s4)
2973 0 : JNI_SET_ARRAY_REGION(Long, jlong, long, s8)
2974 0 : JNI_SET_ARRAY_REGION(Float, jfloat, float, float)
2975 0 : JNI_SET_ARRAY_REGION(Double, jdouble, double, double)
2976 :
2977 :
2978 : /* Registering Native Methods *************************************************/
2979 :
2980 : /* RegisterNatives *************************************************************
2981 :
2982 : Registers native methods with the class specified by the clazz
2983 : argument. The methods parameter specifies an array of
2984 : JNINativeMethod structures that contain the names, signatures, and
2985 : function pointers of the native methods. The nMethods parameter
2986 : specifies the number of native methods in the array.
2987 :
2988 : *******************************************************************************/
2989 :
2990 0 : jint jni_RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods)
2991 : {
2992 0 : TRACEJNICALLS(("jni_RegisterNatives(env=%p, clazz=%p, methods=%p, nMethods=%d)", env, clazz, methods, nMethods));
2993 :
2994 0 : classinfo* c = LLNI_classinfo_unwrap(clazz);
2995 :
2996 0 : NativeMethods& nm = VM::get_current()->get_nativemethods();
2997 0 : nm.register_methods(c->name, methods, nMethods);
2998 :
2999 0 : return 0;
3000 : }
3001 :
3002 :
3003 : /* UnregisterNatives ***********************************************************
3004 :
3005 : Unregisters native methods of a class. The class goes back to the
3006 : state before it was linked or registered with its native method
3007 : functions.
3008 :
3009 : This function should not be used in normal native code. Instead, it
3010 : provides special programs a way to reload and relink native
3011 : libraries.
3012 :
3013 : *******************************************************************************/
3014 :
3015 0 : jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
3016 : {
3017 : STATISTICS(jniinvokation());
3018 :
3019 : /* XXX TWISTI hmm, maybe we should not support that (like kaffe) */
3020 :
3021 0 : log_text("JNI-Call: UnregisterNatives: IMPLEMENT ME!!!");
3022 :
3023 0 : return 0;
3024 : }
3025 :
3026 :
3027 : /* Monitor Operations *********************************************************/
3028 :
3029 : /* MonitorEnter ****************************************************************
3030 :
3031 : Enters the monitor associated with the underlying Java object
3032 : referred to by obj.
3033 :
3034 : *******************************************************************************/
3035 :
3036 0 : jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
3037 : {
3038 : STATISTICS(jniinvokation());
3039 :
3040 0 : if (obj == NULL) {
3041 0 : exceptions_throw_nullpointerexception();
3042 0 : return JNI_ERR;
3043 : }
3044 :
3045 0 : LOCK_MONITOR_ENTER(obj);
3046 :
3047 0 : return JNI_OK;
3048 : }
3049 :
3050 :
3051 : /* MonitorExit *****************************************************************
3052 :
3053 : The current thread must be the owner of the monitor associated with
3054 : the underlying Java object referred to by obj. The thread
3055 : decrements the counter indicating the number of times it has
3056 : entered this monitor. If the value of the counter becomes zero, the
3057 : current thread releases the monitor.
3058 :
3059 : *******************************************************************************/
3060 :
3061 0 : jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
3062 : {
3063 : STATISTICS(jniinvokation());
3064 :
3065 0 : if (obj == NULL) {
3066 0 : exceptions_throw_nullpointerexception();
3067 0 : return JNI_ERR;
3068 : }
3069 :
3070 0 : LOCK_MONITOR_EXIT(obj);
3071 :
3072 0 : return JNI_OK;
3073 : }
3074 :
3075 :
3076 : /* JavaVM Interface ***********************************************************/
3077 :
3078 : /* GetJavaVM *******************************************************************
3079 :
3080 : Returns the Java VM interface (used in the Invocation API)
3081 : associated with the current thread. The result is placed at the
3082 : location pointed to by the second argument, vm.
3083 :
3084 : *******************************************************************************/
3085 :
3086 423 : jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **javavm)
3087 : {
3088 : STATISTICS(jniinvokation());
3089 :
3090 423 : *javavm = VM::get_current()->get_javavm();
3091 :
3092 423 : return 0;
3093 : }
3094 :
3095 :
3096 : /* GetStringRegion *************************************************************
3097 :
3098 : Copies len number of Unicode characters beginning at offset start
3099 : to the given buffer buf.
3100 :
3101 : Throws StringIndexOutOfBoundsException on index overflow.
3102 :
3103 : *******************************************************************************/
3104 :
3105 0 : void jni_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
3106 : {
3107 0 : java_lang_String s(str);
3108 0 : CharArray ca(s.get_value());
3109 0 : int32_t count = runtime_str_ops::get_string_count(s);
3110 :
3111 0 : if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3112 0 : exceptions_throw_stringindexoutofboundsexception();
3113 : return;
3114 : }
3115 :
3116 0 : ca.get_region(start, len, buf);
3117 : }
3118 :
3119 :
3120 : /* GetStringUTFRegion **********************************************************
3121 :
3122 : Translates len number of Unicode characters beginning at offset
3123 : start into UTF-8 format and place the result in the given buffer
3124 : buf.
3125 :
3126 : Throws StringIndexOutOfBoundsException on index overflow.
3127 :
3128 : *******************************************************************************/
3129 :
3130 0 : void jni_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
3131 : {
3132 0 : TRACEJNICALLS(("jni_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf));
3133 :
3134 0 : java_lang_String s(str);
3135 :
3136 0 : CharArray ca(s.get_value());
3137 :
3138 0 : int32_t count = runtime_str_ops::get_string_count(s);
3139 0 : int32_t offset = runtime_str_ops::get_string_offset(s);
3140 :
3141 0 : if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
3142 0 : exceptions_throw_stringindexoutofboundsexception();
3143 : return;
3144 : }
3145 :
3146 : int32_t i;
3147 :
3148 : // XXX: Fix me!
3149 0 : uint16_t* ptr = (uint16_t*) ca.get_raw_data_ptr();
3150 0 : for (i = 0; i < len; i++)
3151 0 : buf[i] = ptr[offset + start + i];
3152 :
3153 0 : buf[i] = '\0';
3154 : }
3155 :
3156 :
3157 : /* GetPrimitiveArrayCritical ***************************************************
3158 :
3159 : Obtain a direct pointer to array elements.
3160 :
3161 : ATTENTION: Critical section keeps open when this function returns!
3162 : See ReleasePrimitiveArrayCritical.
3163 :
3164 : *******************************************************************************/
3165 :
3166 0 : void* jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
3167 : {
3168 : java_handle_t* h;
3169 : java_array_t* a;
3170 : arraydescriptor* ad;
3171 : void* data;
3172 :
3173 0 : TRACEJNICALLS(("jni_GetPrimitiveArrayCritical(env=%p, array=%p, isCopy=%d)", env, array, isCopy));
3174 :
3175 0 : if (isCopy != NULL) {
3176 0 : *isCopy = JNI_FALSE;
3177 : }
3178 :
3179 : LLNI_CRITICAL_START;
3180 :
3181 0 : h = (java_handle_t*) array;
3182 0 : a = (java_array_t*) LLNI_UNWRAP(h);
3183 0 : ad = a->objheader.vftbl->arraydesc;
3184 :
3185 : /* Sanity check. */
3186 :
3187 0 : assert(ad != NULL);
3188 :
3189 0 : data = (void*) (((intptr_t) a) + ad->dataoffset);
3190 :
3191 0 : return data;
3192 : }
3193 :
3194 :
3195 : /* ReleasePrimitiveArrayCritical ***********************************************
3196 :
3197 : No specific documentation.
3198 :
3199 : ATTENTION: This function closes the critical section opened in
3200 : GetPrimitiveArrayCritical!
3201 :
3202 : *******************************************************************************/
3203 :
3204 0 : void jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode)
3205 : {
3206 0 : TRACEJNICALLS(("jni_ReleasePrimitiveArrayCritical(env=%p, array=%p, carray=%p, mode=%d)", env, array, carray, mode));
3207 :
3208 : LLNI_CRITICAL_END;
3209 0 : }
3210 :
3211 :
3212 : /* GetStringCritical ***********************************************************
3213 :
3214 : The semantics of these two functions are similar to the existing
3215 : Get/ReleaseStringChars functions.
3216 :
3217 : *******************************************************************************/
3218 :
3219 0 : const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
3220 : jboolean *isCopy)
3221 : {
3222 : STATISTICS(jniinvokation());
3223 :
3224 0 : return jni_GetStringChars(env, string, isCopy);
3225 : }
3226 :
3227 :
3228 0 : void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
3229 : const jchar *cstring)
3230 : {
3231 : STATISTICS(jniinvokation());
3232 :
3233 0 : _Jv_JNI_ReleaseStringChars(env, string, cstring);
3234 0 : }
3235 :
3236 :
3237 0 : jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
3238 : {
3239 0 : TRACEJNICALLS(("_Jv_JNI_NewWeakGlobalRef(env=%p, obj=%p): IMPLEMENT ME!", env, obj));
3240 :
3241 0 : return (jweak) obj;
3242 : }
3243 :
3244 :
3245 0 : void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
3246 : {
3247 0 : TRACEJNICALLS(("_Jv_JNI_DeleteWeakGlobalRef(env=%p, ref=%p): IMPLEMENT ME", env, ref));
3248 0 : }
3249 :
3250 :
3251 : /* NewGlobalRef ****************************************************************
3252 :
3253 : Creates a new global reference to the object referred to by the obj
3254 : argument.
3255 :
3256 : *******************************************************************************/
3257 :
3258 434 : jobject jni_NewGlobalRef(JNIEnv* env, jobject obj)
3259 : {
3260 : hashtable_global_ref_entry *gre;
3261 : u4 key; /* hashkey */
3262 : u4 slot; /* slot in hashtable */
3263 : java_handle_t *o;
3264 :
3265 434 : TRACEJNICALLS(("jni_NewGlobalRef(env=%p, obj=%p)", env, obj));
3266 :
3267 434 : o = (java_handle_t *) obj;
3268 :
3269 434 : hashtable_global_ref->mutex->lock();
3270 :
3271 : LLNI_CRITICAL_START;
3272 :
3273 : /* normally addresses are aligned to 4, 8 or 16 bytes */
3274 :
3275 434 : key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3276 434 : slot = key & (hashtable_global_ref->size - 1);
3277 434 : gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3278 :
3279 : /* search external hash chain for the entry */
3280 :
3281 868 : while (gre) {
3282 282 : if (gre->o == LLNI_DIRECT(o)) {
3283 : /* global object found, increment the reference */
3284 :
3285 282 : gre->refs++;
3286 :
3287 282 : break;
3288 : }
3289 :
3290 0 : gre = gre->hashlink; /* next element in external chain */
3291 : }
3292 :
3293 : LLNI_CRITICAL_END;
3294 :
3295 : /* global ref not found, create a new one */
3296 :
3297 434 : if (gre == NULL) {
3298 152 : gre = (hashtable_global_ref_entry*) heap_alloc_uncollectable(sizeof(hashtable_global_ref_entry));
3299 :
3300 : #if defined(ENABLE_GC_CACAO)
3301 : /* register global ref with the GC */
3302 :
3303 : gc_reference_register(&(gre->o), GC_REFTYPE_JNI_GLOBALREF);
3304 : #endif
3305 :
3306 : LLNI_CRITICAL_START;
3307 :
3308 152 : gre->o = LLNI_DIRECT(o);
3309 152 : gre->refs = 1;
3310 :
3311 : LLNI_CRITICAL_END;
3312 :
3313 : /* insert entry into hashtable */
3314 :
3315 152 : gre->hashlink = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3316 :
3317 152 : hashtable_global_ref->ptr[slot] = gre;
3318 :
3319 : /* update number of hashtable-entries */
3320 :
3321 152 : hashtable_global_ref->entries++;
3322 : }
3323 :
3324 434 : hashtable_global_ref->mutex->unlock();
3325 :
3326 : #if defined(ENABLE_HANDLES)
3327 : return gre;
3328 : #else
3329 434 : return obj;
3330 : #endif
3331 : }
3332 :
3333 :
3334 : /* DeleteGlobalRef *************************************************************
3335 :
3336 : Deletes the global reference pointed to by globalRef.
3337 :
3338 : *******************************************************************************/
3339 :
3340 0 : void jni_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
3341 : {
3342 : hashtable_global_ref_entry *gre;
3343 : hashtable_global_ref_entry *prevgre;
3344 : u4 key; /* hashkey */
3345 : u4 slot; /* slot in hashtable */
3346 : java_handle_t *o;
3347 :
3348 0 : TRACEJNICALLS(("jni_DeleteGlobalRef(env=%p, globalRef=%p)", env, globalRef));
3349 :
3350 0 : o = (java_handle_t *) globalRef;
3351 :
3352 0 : hashtable_global_ref->mutex->lock();
3353 :
3354 : LLNI_CRITICAL_START;
3355 :
3356 : /* normally addresses are aligned to 4, 8 or 16 bytes */
3357 :
3358 0 : key = heap_hashcode(LLNI_DIRECT(o)) >> 4; /* align to 16-byte boundaries */
3359 0 : slot = key & (hashtable_global_ref->size - 1);
3360 0 : gre = (hashtable_global_ref_entry*) hashtable_global_ref->ptr[slot];
3361 :
3362 : /* initialize prevgre */
3363 :
3364 0 : prevgre = NULL;
3365 :
3366 : /* search external hash chain for the entry */
3367 :
3368 0 : while (gre) {
3369 0 : if (gre->o == LLNI_DIRECT(o)) {
3370 : /* global object found, decrement the reference count */
3371 :
3372 0 : gre->refs--;
3373 :
3374 : /* if reference count is 0, remove the entry */
3375 :
3376 0 : if (gre->refs == 0) {
3377 : /* special handling if it's the first in the chain */
3378 :
3379 0 : if (prevgre == NULL)
3380 0 : hashtable_global_ref->ptr[slot] = gre->hashlink;
3381 : else
3382 0 : prevgre->hashlink = gre->hashlink;
3383 :
3384 : #if defined(ENABLE_GC_CACAO)
3385 : /* unregister global ref with the GC */
3386 :
3387 : gc_reference_unregister(&(gre->o));
3388 : #endif
3389 :
3390 0 : heap_free(gre);
3391 : }
3392 :
3393 : LLNI_CRITICAL_END;
3394 :
3395 0 : hashtable_global_ref->mutex->unlock();
3396 :
3397 0 : return;
3398 : }
3399 :
3400 0 : prevgre = gre; /* save current pointer for removal */
3401 0 : gre = gre->hashlink; /* next element in external chain */
3402 : }
3403 :
3404 0 : log_println("jni_DeleteGlobalRef: Global reference not found.");
3405 :
3406 : LLNI_CRITICAL_END;
3407 :
3408 0 : hashtable_global_ref->mutex->unlock();
3409 : }
3410 :
3411 :
3412 : /* ExceptionCheck **************************************************************
3413 :
3414 : Returns JNI_TRUE when there is a pending exception; otherwise,
3415 : returns JNI_FALSE.
3416 :
3417 : *******************************************************************************/
3418 :
3419 5 : jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
3420 : {
3421 : java_handle_t *o;
3422 :
3423 : STATISTICS(jniinvokation());
3424 :
3425 5 : o = exceptions_get_exception();
3426 :
3427 5 : return (o != NULL) ? JNI_TRUE : JNI_FALSE;
3428 : }
3429 :
3430 :
3431 : /* New JNI 1.4 functions ******************************************************/
3432 :
3433 : /* NewDirectByteBuffer *********************************************************
3434 :
3435 : Allocates and returns a direct java.nio.ByteBuffer referring to the
3436 : block of memory starting at the memory address address and
3437 : extending capacity bytes.
3438 :
3439 : *******************************************************************************/
3440 :
3441 0 : jobject jni_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
3442 : {
3443 : #if defined(ENABLE_JAVASE)
3444 : # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3445 0 : TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3446 :
3447 : // Allocate a gnu.classpath.Pointer{32,64} object.
3448 :
3449 : # if SIZEOF_VOID_P == 8
3450 0 : java_handle_t* h = builtin_new(class_gnu_classpath_Pointer64);
3451 : # else
3452 : java_handle_t* h = builtin_new(class_gnu_classpath_Pointer32);
3453 : # endif
3454 :
3455 0 : if (h == NULL)
3456 0 : return NULL;
3457 :
3458 0 : gnu_classpath_Pointer p(h, address);
3459 :
3460 : // Create a java.nio.DirectByteBufferImpl$ReadWrite object.
3461 :
3462 : java_handle_t* nbuf =
3463 : (java_handle_t*) jni_NewObject(env, (jclass) class_java_nio_DirectByteBufferImpl_ReadWrite,
3464 : (jmethodID) dbbirw_init, NULL, p.get_handle(),
3465 0 : (jint) capacity, (jint) capacity, (jint) 0);
3466 :
3467 : // Add a local reference and return the value.
3468 :
3469 0 : TRACEJNICALLSEXIT(("->%p", nbuf));
3470 :
3471 0 : return jni_NewLocalRef(env, (jobject) nbuf);
3472 :
3473 : # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3474 :
3475 : jobject o;
3476 : int64_t addr;
3477 : int32_t cap;
3478 :
3479 : TRACEJNICALLSENTER(("jni_NewDirectByteBuffer(env=%p, address=%p, capacity=%ld)", env, address, capacity));
3480 :
3481 : /* Be paranoid about address sign-extension. */
3482 :
3483 : addr = (int64_t) ((uintptr_t) address);
3484 : cap = (int32_t) capacity;
3485 :
3486 : o = jni_NewObject(env, (jclass) class_java_nio_DirectByteBuffer,
3487 : (jmethodID) dbb_init, addr, cap);
3488 :
3489 : /* Add local reference and return the value. */
3490 :
3491 : TRACEJNICALLSEXIT(("->%p", o));
3492 :
3493 : return jni_NewLocalRef(env, o);
3494 :
3495 : # else
3496 : # error unknown classpath configuration
3497 : # endif
3498 :
3499 : #else
3500 : vm_abort("jni_NewDirectByteBuffer: Not implemented in this configuration.");
3501 :
3502 : /* keep compiler happy */
3503 :
3504 : return NULL;
3505 : #endif
3506 : }
3507 :
3508 :
3509 : /* GetDirectBufferAddress ******************************************************
3510 :
3511 : Fetches and returns the starting address of the memory region
3512 : referenced by the given direct java.nio.Buffer.
3513 :
3514 : *******************************************************************************/
3515 :
3516 94906 : void* jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
3517 : {
3518 : #if defined(ENABLE_JAVASE)
3519 : # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3520 :
3521 94906 : TRACEJNICALLSENTER(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3522 :
3523 : /* Prevent compiler warning. */
3524 :
3525 94906 : java_handle_t* h = (java_handle_t *) buf;
3526 :
3527 94906 : if ((h != NULL) && !builtin_instanceof(h, class_java_nio_Buffer))
3528 0 : return NULL;
3529 :
3530 94906 : java_nio_DirectByteBufferImpl dbb(buf);
3531 94906 : java_handle_t* address = dbb.get_address();
3532 :
3533 94906 : if (address == NULL) {
3534 94906 : TRACEJNICALLSEXIT(("->%p", NULL));
3535 94906 : return NULL;
3536 : }
3537 :
3538 0 : gnu_classpath_Pointer p(address);
3539 0 : void* data = p.get_data();
3540 :
3541 0 : TRACEJNICALLSEXIT(("->%p", data));
3542 :
3543 0 : return data;
3544 :
3545 : # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3546 :
3547 : TRACEJNICALLS(("jni_GetDirectBufferAddress(env=%p, buf=%p)", env, buf));
3548 :
3549 : java_nio_Buffer jnb(buf);
3550 :
3551 : if (jnb.is_non_null() && !builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
3552 : return NULL;
3553 :
3554 : void* address = jnb.get_address();
3555 :
3556 : return address;
3557 :
3558 : # else
3559 : # error unknown classpath configuration
3560 : # endif
3561 :
3562 : #else
3563 :
3564 : vm_abort("jni_GetDirectBufferAddress: Not implemented in this configuration.");
3565 :
3566 : // Keep compiler happy.
3567 : return NULL;
3568 :
3569 : #endif
3570 : }
3571 :
3572 :
3573 : /* GetDirectBufferCapacity *****************************************************
3574 :
3575 : Fetches and returns the capacity in bytes of the memory region
3576 : referenced by the given direct java.nio.Buffer.
3577 :
3578 : *******************************************************************************/
3579 :
3580 0 : jlong jni_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
3581 : {
3582 : #if defined(ENABLE_JAVASE)
3583 : # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
3584 0 : TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
3585 :
3586 0 : java_handle_t* h = (java_handle_t *) buf;
3587 :
3588 0 : if (!builtin_instanceof(h, class_java_nio_DirectByteBufferImpl))
3589 0 : return -1;
3590 :
3591 0 : java_nio_Buffer b(h);
3592 0 : jlong capacity = b.get_cap();
3593 :
3594 0 : return capacity;
3595 : # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
3596 :
3597 : TRACEJNICALLS(("jni_GetDirectBufferCapacity(env=%p, buf=%p)", env, buf));
3598 :
3599 : java_nio_Buffer jnb(buf);
3600 :
3601 : if (!builtin_instanceof(jnb.get_handle(), class_sun_nio_ch_DirectBuffer))
3602 : return -1;
3603 :
3604 : jlong capacity = jnb.get_capacity();
3605 :
3606 : return capacity;
3607 :
3608 : # else
3609 : # error unknown classpath configuration
3610 : # endif
3611 :
3612 : #else
3613 : vm_abort("jni_GetDirectBufferCapacity: not implemented in this configuration");
3614 :
3615 : // Keep compiler happy.
3616 :
3617 : return 0;
3618 : #endif
3619 : }
3620 :
3621 :
3622 : /* GetObjectRefType ************************************************************
3623 :
3624 : Returns the type of the object referred to by the obj argument. The
3625 : argument obj can either be a local, global or weak global
3626 : reference.
3627 :
3628 : *******************************************************************************/
3629 :
3630 0 : jobjectRefType jni_GetObjectRefType(JNIEnv *env, jobject obj)
3631 : {
3632 0 : log_println("jni_GetObjectRefType: IMPLEMENT ME!");
3633 :
3634 0 : return (jobjectRefType) NULL;
3635 : }
3636 :
3637 :
3638 : /* DestroyJavaVM ***************************************************************
3639 :
3640 : Unloads a Java VM and reclaims its resources. Only the main thread
3641 : can unload the VM. The system waits until the main thread is only
3642 : remaining user thread before it destroys the VM.
3643 :
3644 : *******************************************************************************/
3645 :
3646 0 : jint _Jv_JNI_DestroyJavaVM(JavaVM *javavm)
3647 : {
3648 : int status;
3649 :
3650 0 : TRACEJNICALLS(("_Jv_JNI_DestroyJavaVM(javavm=%p)", javavm));
3651 :
3652 0 : if (VM::get_current()->is_created() == false)
3653 0 : return JNI_ERR;
3654 :
3655 0 : status = vm_destroy(javavm);
3656 :
3657 0 : return status;
3658 : }
3659 :
3660 :
3661 : /* AttachCurrentThread *********************************************************
3662 :
3663 : Attaches the current thread to a Java VM. Returns a JNI interface
3664 : pointer in the JNIEnv argument.
3665 :
3666 : Trying to attach a thread that is already attached is a no-op.
3667 :
3668 : A native thread cannot be attached simultaneously to two Java VMs.
3669 :
3670 : When a thread is attached to the VM, the context class loader is
3671 : the bootstrap loader.
3672 :
3673 : *******************************************************************************/
3674 :
3675 0 : static int jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
3676 : {
3677 : /* If the current thread has already been attached, this operation
3678 : is a no-op. */
3679 :
3680 0 : bool result = thread_current_is_attached();
3681 :
3682 0 : if (result == true) {
3683 0 : *p_env = VM::get_current()->get_jnienv();
3684 0 : return JNI_OK;
3685 : }
3686 :
3687 0 : JavaVMAttachArgs *vm_aargs = (JavaVMAttachArgs *) thr_args;
3688 :
3689 0 : if (vm_aargs != NULL) {
3690 0 : if ((vm_aargs->version != JNI_VERSION_1_2) &&
3691 : (vm_aargs->version != JNI_VERSION_1_4))
3692 0 : return JNI_EVERSION;
3693 : }
3694 :
3695 0 : if (!thread_attach_current_external_thread(vm_aargs, false))
3696 0 : return JNI_ERR;
3697 :
3698 0 : if (!localref_table_init())
3699 0 : return JNI_ERR;
3700 :
3701 0 : *p_env = VM::get_current()->get_jnienv();
3702 :
3703 0 : return JNI_OK;
3704 : }
3705 :
3706 :
3707 0 : jint jni_AttachCurrentThread(JavaVM *javavm, void **p_env, void *thr_args)
3708 : {
3709 : int result;
3710 :
3711 0 : TRACEJNICALLS(("jni_AttachCurrentThread(javavm=%p, p_env=%p, thr_args=%p)", javavm, p_env, thr_args));
3712 :
3713 0 : if (VM::get_current()->is_created() == false)
3714 0 : return JNI_ERR;
3715 :
3716 0 : result = jni_attach_current_thread(p_env, thr_args, false);
3717 :
3718 0 : return result;
3719 : }
3720 :
3721 :
3722 : /* DetachCurrentThread *********************************************************
3723 :
3724 : Detaches the current thread from a Java VM. All Java monitors held
3725 : by this thread are released. All Java threads waiting for this
3726 : thread to die are notified.
3727 :
3728 : In JDK 1.1, the main thread cannot be detached from the VM. It must
3729 : call DestroyJavaVM to unload the entire VM.
3730 :
3731 : In the JDK, the main thread can be detached from the VM.
3732 :
3733 : The main thread, which is the thread that created the Java VM,
3734 : cannot be detached from the VM. Instead, the main thread must call
3735 : JNI_DestroyJavaVM() to unload the entire VM.
3736 :
3737 : *******************************************************************************/
3738 :
3739 0 : jint jni_DetachCurrentThread(JavaVM *vm)
3740 : {
3741 0 : TRACEJNICALLS(("jni_DetachCurrentThread(vm=%p)", vm));
3742 :
3743 : /* If the current thread has already been detached, this operation
3744 : is a no-op. */
3745 :
3746 0 : bool result = thread_current_is_attached();
3747 :
3748 0 : if (result == false)
3749 0 : return true;
3750 :
3751 : /* We need to pop all frames before we can destroy the table. */
3752 :
3753 0 : localref_frame_pop_all();
3754 :
3755 0 : if (!localref_table_destroy())
3756 0 : return JNI_ERR;
3757 :
3758 0 : if (!thread_detach_current_external_thread())
3759 0 : return JNI_ERR;
3760 :
3761 0 : return JNI_OK;
3762 : }
3763 :
3764 :
3765 : /* GetEnv **********************************************************************
3766 :
3767 : If the current thread is not attached to the VM, sets *env to NULL,
3768 : and returns JNI_EDETACHED. If the specified version is not
3769 : supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise,
3770 : sets *env to the appropriate interface, and returns JNI_OK.
3771 :
3772 : *******************************************************************************/
3773 :
3774 423 : jint jni_GetEnv(JavaVM *javavm, void **env, jint version)
3775 : {
3776 423 : TRACEJNICALLS(("jni_GetEnv(javavm=%p, env=%p, version=%d)", javavm, env, version));
3777 :
3778 423 : if (VM::get_current()->is_created() == false) {
3779 0 : *env = NULL;
3780 0 : return JNI_EDETACHED;
3781 : }
3782 :
3783 423 : if (thread_get_current() == NULL) {
3784 0 : *env = NULL;
3785 :
3786 0 : return JNI_EDETACHED;
3787 : }
3788 :
3789 : /* Check the JNI version. */
3790 :
3791 423 : if (jni_version_check(version) == true) {
3792 423 : *env = VM::get_current()->get_jnienv();
3793 423 : return JNI_OK;
3794 : }
3795 :
3796 : #if defined(ENABLE_JVMTI)
3797 : if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) == JVMTI_VERSION_INTERFACE_JVMTI) {
3798 : *env = (void *) jvmti_new_environment();
3799 :
3800 : if (env != NULL)
3801 : return JNI_OK;
3802 : }
3803 : #endif
3804 :
3805 0 : *env = NULL;
3806 :
3807 0 : return JNI_EVERSION;
3808 : }
3809 :
3810 :
3811 : /* AttachCurrentThreadAsDaemon *************************************************
3812 :
3813 : Same semantics as AttachCurrentThread, but the newly-created
3814 : java.lang.Thread instance is a daemon.
3815 :
3816 : If the thread has already been attached via either
3817 : AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
3818 : simply sets the value pointed to by penv to the JNIEnv of the
3819 : current thread. In this case neither AttachCurrentThread nor this
3820 : routine have any effect on the daemon status of the thread.
3821 :
3822 : *******************************************************************************/
3823 :
3824 0 : jint jni_AttachCurrentThreadAsDaemon(JavaVM *javavm, void **penv, void *args)
3825 : {
3826 : int result;
3827 :
3828 0 : TRACEJNICALLS(("jni_AttachCurrentThreadAsDaemon(javavm=%p, penv=%p, args=%p)", javavm, penv, args));
3829 :
3830 0 : if (VM::get_current()->is_created() == false)
3831 0 : return JNI_ERR;
3832 :
3833 0 : result = jni_attach_current_thread(penv, args, true);
3834 :
3835 0 : return result;
3836 : }
3837 :
3838 :
3839 : /* JNI invocation table *******************************************************/
3840 :
3841 : const JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
3842 : NULL,
3843 : NULL,
3844 : NULL,
3845 :
3846 : _Jv_JNI_DestroyJavaVM,
3847 : jni_AttachCurrentThread,
3848 : jni_DetachCurrentThread,
3849 : jni_GetEnv,
3850 : jni_AttachCurrentThreadAsDaemon
3851 : };
3852 :
3853 :
3854 : /* JNI function table *********************************************************/
3855 :
3856 : JNINativeInterface_ _Jv_JNINativeInterface = {
3857 : NULL,
3858 : NULL,
3859 : NULL,
3860 : NULL,
3861 : _Jv_JNI_GetVersion,
3862 :
3863 : jni_DefineClass,
3864 : jni_FindClass,
3865 : jni_FromReflectedMethod,
3866 : jni_FromReflectedField,
3867 : jni_ToReflectedMethod,
3868 : jni_GetSuperclass,
3869 : _Jv_JNI_IsAssignableFrom,
3870 : _Jv_JNI_ToReflectedField,
3871 :
3872 : _Jv_JNI_Throw,
3873 : _Jv_JNI_ThrowNew,
3874 : _Jv_JNI_ExceptionOccurred,
3875 : jni_ExceptionDescribe,
3876 : jni_ExceptionClear,
3877 : _Jv_JNI_FatalError,
3878 : jni_PushLocalFrame,
3879 : jni_PopLocalFrame,
3880 :
3881 : jni_NewGlobalRef,
3882 : jni_DeleteGlobalRef,
3883 : jni_DeleteLocalRef,
3884 : _Jv_JNI_IsSameObject,
3885 : jni_NewLocalRef,
3886 : jni_EnsureLocalCapacity,
3887 :
3888 : _Jv_JNI_AllocObject,
3889 : jni_NewObject,
3890 : _Jv_JNI_NewObjectV,
3891 : _Jv_JNI_NewObjectA,
3892 :
3893 : jni_GetObjectClass,
3894 : _Jv_JNI_IsInstanceOf,
3895 :
3896 : _Jv_JNI_GetMethodID,
3897 :
3898 : _Jv_JNI_CallObjectMethod,
3899 : _Jv_JNI_CallObjectMethodV,
3900 : _Jv_JNI_CallObjectMethodA,
3901 : _Jv_JNI_CallBooleanMethod,
3902 : _Jv_JNI_CallBooleanMethodV,
3903 : _Jv_JNI_CallBooleanMethodA,
3904 : _Jv_JNI_CallByteMethod,
3905 : _Jv_JNI_CallByteMethodV,
3906 : _Jv_JNI_CallByteMethodA,
3907 : _Jv_JNI_CallCharMethod,
3908 : _Jv_JNI_CallCharMethodV,
3909 : _Jv_JNI_CallCharMethodA,
3910 : _Jv_JNI_CallShortMethod,
3911 : _Jv_JNI_CallShortMethodV,
3912 : _Jv_JNI_CallShortMethodA,
3913 : _Jv_JNI_CallIntMethod,
3914 : _Jv_JNI_CallIntMethodV,
3915 : _Jv_JNI_CallIntMethodA,
3916 : _Jv_JNI_CallLongMethod,
3917 : _Jv_JNI_CallLongMethodV,
3918 : _Jv_JNI_CallLongMethodA,
3919 : _Jv_JNI_CallFloatMethod,
3920 : _Jv_JNI_CallFloatMethodV,
3921 : _Jv_JNI_CallFloatMethodA,
3922 : _Jv_JNI_CallDoubleMethod,
3923 : _Jv_JNI_CallDoubleMethodV,
3924 : _Jv_JNI_CallDoubleMethodA,
3925 : _Jv_JNI_CallVoidMethod,
3926 : _Jv_JNI_CallVoidMethodV,
3927 : _Jv_JNI_CallVoidMethodA,
3928 :
3929 : _Jv_JNI_CallNonvirtualObjectMethod,
3930 : _Jv_JNI_CallNonvirtualObjectMethodV,
3931 : _Jv_JNI_CallNonvirtualObjectMethodA,
3932 : _Jv_JNI_CallNonvirtualBooleanMethod,
3933 : _Jv_JNI_CallNonvirtualBooleanMethodV,
3934 : _Jv_JNI_CallNonvirtualBooleanMethodA,
3935 : _Jv_JNI_CallNonvirtualByteMethod,
3936 : _Jv_JNI_CallNonvirtualByteMethodV,
3937 : _Jv_JNI_CallNonvirtualByteMethodA,
3938 : _Jv_JNI_CallNonvirtualCharMethod,
3939 : _Jv_JNI_CallNonvirtualCharMethodV,
3940 : _Jv_JNI_CallNonvirtualCharMethodA,
3941 : _Jv_JNI_CallNonvirtualShortMethod,
3942 : _Jv_JNI_CallNonvirtualShortMethodV,
3943 : _Jv_JNI_CallNonvirtualShortMethodA,
3944 : _Jv_JNI_CallNonvirtualIntMethod,
3945 : _Jv_JNI_CallNonvirtualIntMethodV,
3946 : _Jv_JNI_CallNonvirtualIntMethodA,
3947 : _Jv_JNI_CallNonvirtualLongMethod,
3948 : _Jv_JNI_CallNonvirtualLongMethodV,
3949 : _Jv_JNI_CallNonvirtualLongMethodA,
3950 : _Jv_JNI_CallNonvirtualFloatMethod,
3951 : _Jv_JNI_CallNonvirtualFloatMethodV,
3952 : _Jv_JNI_CallNonvirtualFloatMethodA,
3953 : _Jv_JNI_CallNonvirtualDoubleMethod,
3954 : _Jv_JNI_CallNonvirtualDoubleMethodV,
3955 : _Jv_JNI_CallNonvirtualDoubleMethodA,
3956 : _Jv_JNI_CallNonvirtualVoidMethod,
3957 : _Jv_JNI_CallNonvirtualVoidMethodV,
3958 : _Jv_JNI_CallNonvirtualVoidMethodA,
3959 :
3960 : _Jv_JNI_GetFieldID,
3961 :
3962 : _Jv_JNI_GetObjectField,
3963 : _Jv_JNI_GetBooleanField,
3964 : _Jv_JNI_GetByteField,
3965 : _Jv_JNI_GetCharField,
3966 : _Jv_JNI_GetShortField,
3967 : _Jv_JNI_GetIntField,
3968 : _Jv_JNI_GetLongField,
3969 : _Jv_JNI_GetFloatField,
3970 : _Jv_JNI_GetDoubleField,
3971 : _Jv_JNI_SetObjectField,
3972 : _Jv_JNI_SetBooleanField,
3973 : _Jv_JNI_SetByteField,
3974 : _Jv_JNI_SetCharField,
3975 : _Jv_JNI_SetShortField,
3976 : _Jv_JNI_SetIntField,
3977 : _Jv_JNI_SetLongField,
3978 : _Jv_JNI_SetFloatField,
3979 : _Jv_JNI_SetDoubleField,
3980 :
3981 : _Jv_JNI_GetStaticMethodID,
3982 :
3983 : _Jv_JNI_CallStaticObjectMethod,
3984 : _Jv_JNI_CallStaticObjectMethodV,
3985 : _Jv_JNI_CallStaticObjectMethodA,
3986 : _Jv_JNI_CallStaticBooleanMethod,
3987 : _Jv_JNI_CallStaticBooleanMethodV,
3988 : _Jv_JNI_CallStaticBooleanMethodA,
3989 : _Jv_JNI_CallStaticByteMethod,
3990 : _Jv_JNI_CallStaticByteMethodV,
3991 : _Jv_JNI_CallStaticByteMethodA,
3992 : _Jv_JNI_CallStaticCharMethod,
3993 : _Jv_JNI_CallStaticCharMethodV,
3994 : _Jv_JNI_CallStaticCharMethodA,
3995 : _Jv_JNI_CallStaticShortMethod,
3996 : _Jv_JNI_CallStaticShortMethodV,
3997 : _Jv_JNI_CallStaticShortMethodA,
3998 : _Jv_JNI_CallStaticIntMethod,
3999 : _Jv_JNI_CallStaticIntMethodV,
4000 : _Jv_JNI_CallStaticIntMethodA,
4001 : _Jv_JNI_CallStaticLongMethod,
4002 : _Jv_JNI_CallStaticLongMethodV,
4003 : _Jv_JNI_CallStaticLongMethodA,
4004 : _Jv_JNI_CallStaticFloatMethod,
4005 : _Jv_JNI_CallStaticFloatMethodV,
4006 : _Jv_JNI_CallStaticFloatMethodA,
4007 : _Jv_JNI_CallStaticDoubleMethod,
4008 : _Jv_JNI_CallStaticDoubleMethodV,
4009 : _Jv_JNI_CallStaticDoubleMethodA,
4010 : _Jv_JNI_CallStaticVoidMethod,
4011 : _Jv_JNI_CallStaticVoidMethodV,
4012 : _Jv_JNI_CallStaticVoidMethodA,
4013 :
4014 : _Jv_JNI_GetStaticFieldID,
4015 :
4016 : _Jv_JNI_GetStaticObjectField,
4017 : _Jv_JNI_GetStaticBooleanField,
4018 : _Jv_JNI_GetStaticByteField,
4019 : _Jv_JNI_GetStaticCharField,
4020 : _Jv_JNI_GetStaticShortField,
4021 : _Jv_JNI_GetStaticIntField,
4022 : _Jv_JNI_GetStaticLongField,
4023 : _Jv_JNI_GetStaticFloatField,
4024 : _Jv_JNI_GetStaticDoubleField,
4025 : _Jv_JNI_SetStaticObjectField,
4026 : _Jv_JNI_SetStaticBooleanField,
4027 : _Jv_JNI_SetStaticByteField,
4028 : _Jv_JNI_SetStaticCharField,
4029 : _Jv_JNI_SetStaticShortField,
4030 : _Jv_JNI_SetStaticIntField,
4031 : _Jv_JNI_SetStaticLongField,
4032 : _Jv_JNI_SetStaticFloatField,
4033 : _Jv_JNI_SetStaticDoubleField,
4034 :
4035 : jni_NewString,
4036 : jni_GetStringLength,
4037 : jni_GetStringChars,
4038 : _Jv_JNI_ReleaseStringChars,
4039 :
4040 : jni_NewStringUTF,
4041 : jni_GetStringUTFLength,
4042 : _Jv_JNI_GetStringUTFChars,
4043 : _Jv_JNI_ReleaseStringUTFChars,
4044 :
4045 : _Jv_JNI_GetArrayLength,
4046 :
4047 : _Jv_JNI_NewObjectArray,
4048 : _Jv_JNI_GetObjectArrayElement,
4049 : _Jv_JNI_SetObjectArrayElement,
4050 :
4051 : _Jv_JNI_NewBooleanArray,
4052 : _Jv_JNI_NewByteArray,
4053 : _Jv_JNI_NewCharArray,
4054 : _Jv_JNI_NewShortArray,
4055 : _Jv_JNI_NewIntArray,
4056 : _Jv_JNI_NewLongArray,
4057 : _Jv_JNI_NewFloatArray,
4058 : _Jv_JNI_NewDoubleArray,
4059 :
4060 : _Jv_JNI_GetBooleanArrayElements,
4061 : _Jv_JNI_GetByteArrayElements,
4062 : _Jv_JNI_GetCharArrayElements,
4063 : _Jv_JNI_GetShortArrayElements,
4064 : _Jv_JNI_GetIntArrayElements,
4065 : _Jv_JNI_GetLongArrayElements,
4066 : _Jv_JNI_GetFloatArrayElements,
4067 : _Jv_JNI_GetDoubleArrayElements,
4068 :
4069 : _Jv_JNI_ReleaseBooleanArrayElements,
4070 : _Jv_JNI_ReleaseByteArrayElements,
4071 : _Jv_JNI_ReleaseCharArrayElements,
4072 : _Jv_JNI_ReleaseShortArrayElements,
4073 : _Jv_JNI_ReleaseIntArrayElements,
4074 : _Jv_JNI_ReleaseLongArrayElements,
4075 : _Jv_JNI_ReleaseFloatArrayElements,
4076 : _Jv_JNI_ReleaseDoubleArrayElements,
4077 :
4078 : _Jv_JNI_GetBooleanArrayRegion,
4079 : _Jv_JNI_GetByteArrayRegion,
4080 : _Jv_JNI_GetCharArrayRegion,
4081 : _Jv_JNI_GetShortArrayRegion,
4082 : _Jv_JNI_GetIntArrayRegion,
4083 : _Jv_JNI_GetLongArrayRegion,
4084 : _Jv_JNI_GetFloatArrayRegion,
4085 : _Jv_JNI_GetDoubleArrayRegion,
4086 : _Jv_JNI_SetBooleanArrayRegion,
4087 : _Jv_JNI_SetByteArrayRegion,
4088 : _Jv_JNI_SetCharArrayRegion,
4089 : _Jv_JNI_SetShortArrayRegion,
4090 : _Jv_JNI_SetIntArrayRegion,
4091 : _Jv_JNI_SetLongArrayRegion,
4092 : _Jv_JNI_SetFloatArrayRegion,
4093 : _Jv_JNI_SetDoubleArrayRegion,
4094 :
4095 : jni_RegisterNatives,
4096 : _Jv_JNI_UnregisterNatives,
4097 :
4098 : _Jv_JNI_MonitorEnter,
4099 : _Jv_JNI_MonitorExit,
4100 :
4101 : _Jv_JNI_GetJavaVM,
4102 :
4103 : /* New JNI 1.2 functions. */
4104 :
4105 : jni_GetStringRegion,
4106 : jni_GetStringUTFRegion,
4107 :
4108 : jni_GetPrimitiveArrayCritical,
4109 : jni_ReleasePrimitiveArrayCritical,
4110 :
4111 : _Jv_JNI_GetStringCritical,
4112 : _Jv_JNI_ReleaseStringCritical,
4113 :
4114 : _Jv_JNI_NewWeakGlobalRef,
4115 : _Jv_JNI_DeleteWeakGlobalRef,
4116 :
4117 : _Jv_JNI_ExceptionCheck,
4118 :
4119 : /* New JNI 1.4 functions. */
4120 :
4121 : jni_NewDirectByteBuffer,
4122 : jni_GetDirectBufferAddress,
4123 : jni_GetDirectBufferCapacity,
4124 :
4125 : /* New JNI 1.6 functions. */
4126 :
4127 : jni_GetObjectRefType
4128 : };
4129 :
4130 :
4131 : /* Invocation API Functions ***************************************************/
4132 :
4133 : /* JNI_GetDefaultJavaVMInitArgs ************************************************
4134 :
4135 : Returns a default configuration for the Java VM.
4136 :
4137 : *******************************************************************************/
4138 :
4139 0 : jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
4140 : {
4141 : JavaVMInitArgs *_vm_args;
4142 :
4143 0 : _vm_args = (JavaVMInitArgs *) vm_args;
4144 :
4145 : /* GNU classpath currently supports JNI 1.2 */
4146 :
4147 0 : switch (_vm_args->version) {
4148 : case JNI_VERSION_1_1:
4149 0 : _vm_args->version = JNI_VERSION_1_1;
4150 0 : break;
4151 :
4152 : case JNI_VERSION_1_2:
4153 : case JNI_VERSION_1_4:
4154 0 : _vm_args->ignoreUnrecognized = JNI_FALSE;
4155 0 : _vm_args->options = NULL;
4156 0 : _vm_args->nOptions = 0;
4157 0 : break;
4158 :
4159 : case JNI_VERSION_CACAO:
4160 : // We reveal ourselves by accepting this version number,
4161 : // this actually means we are using the supported JNI version.
4162 0 : _vm_args->version = JNI_VERSION_SUPPORTED;
4163 0 : break;
4164 :
4165 : default:
4166 0 : return JNI_ERR;
4167 : }
4168 :
4169 0 : return JNI_OK;
4170 : }
4171 :
4172 :
4173 : /* JNI_GetCreatedJavaVMs *******************************************************
4174 :
4175 : Returns all Java VMs that have been created. Pointers to VMs are written in
4176 : the buffer vmBuf in the order they are created. At most bufLen number of
4177 : entries will be written. The total number of created VMs is returned in
4178 : *nVMs.
4179 :
4180 : *******************************************************************************/
4181 :
4182 0 : jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
4183 : {
4184 0 : TRACEJNICALLS(("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs));
4185 :
4186 0 : if (bufLen <= 0)
4187 0 : return JNI_ERR;
4188 :
4189 : // We currently only support 1 VM running.
4190 :
4191 0 : vmBuf[0] = VM::get_current()->get_javavm();
4192 0 : *nVMs = 1;
4193 :
4194 0 : return JNI_OK;
4195 : }
4196 :
4197 :
4198 : /* JNI_CreateJavaVM ************************************************************
4199 :
4200 : Loads and initializes a Java VM. The current thread becomes the main thread.
4201 : Sets the env argument to the JNI interface pointer of the main thread.
4202 :
4203 : *******************************************************************************/
4204 :
4205 0 : jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
4206 : {
4207 0 : TRACEJNICALLS(("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args));
4208 :
4209 : /* actually create the JVM */
4210 :
4211 0 : if (!VM_create(p_vm, p_env, vm_args))
4212 0 : return JNI_ERR;
4213 :
4214 0 : return JNI_OK;
4215 : }
4216 :
4217 : } // extern "C"
4218 :
4219 :
4220 : /*
4221 : * These are local overrides for various environment variables in Emacs.
4222 : * Please do not remove this and leave it at the end of the file, where
4223 : * Emacs will automagically detect them.
4224 : * ---------------------------------------------------------------------
4225 : * Local variables:
4226 : * mode: c++
4227 : * indent-tabs-mode: t
4228 : * c-basic-offset: 4
4229 : * tab-width: 4
4230 : * End:
4231 : * vim:noexpandtab:sw=4:ts=4:
4232 : */
|