LCOV - code coverage report
Current view: top level - native - jni.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 264 957 27.6 %
Date: 2015-06-10 18:10:59 Functions: 52 252 20.6 %

          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       94905 :         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             :  */

Generated by: LCOV version 1.11