This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / ikvm-jni / mono-jni.c
1 /*
2  * mono-jni.c: native methods required by the mono JNI implementation.
3  *
4  *
5  */
6
7 #include <jni.h>
8 #include <gmodule.h>
9 #include <mono/metadata/object.h>
10 #include <mono/metadata/appdomain.h>
11
12 #include <string.h>
13 #include <stdarg.h>
14
15 /*
16  * PROTOTYPES
17  */
18
19 void * native_load_native_library (char *filename);
20
21 int native_lookup_symbol (GModule *module, char *symbol_name, gpointer *symbol);
22 void mono_jni_jnienv_init (
23         void *makelocalref_func,
24         void *unwrap_func,
25         void *makeglobalref_func,
26         void *deleteref_func,
27         void *getfieldcookie_func,
28         void *getmethodcookie_func,
29         void *setfieldvalue_func,
30         void *getfieldvalue_func,
31         void *getclassfromobject_func,
32         void *exceptioncheck_func,
33         void *getpendingexception_func,
34         void *setpendingexception_func,
35         void *invokemethod_func,
36         void *getmethodarglist_func,
37         void *findclass_func,
38         void *getjnienv_func,
39         void *allocobject_func);
40
41 void* mono_jni_get_func_table (void);
42
43 void mono_jni_set_jnifunc (int index, void *func);
44
45 jint JNICALL GetJavaVM (JNIEnv *env, JavaVM **vm);
46
47
48 void *
49 native_load_native_library (char *filename)
50 {
51         return g_module_open (filename, 0);
52 }
53
54 int 
55 native_lookup_symbol (GModule *module, char *symbol_name, gpointer *symbol)
56 {
57         gboolean res = g_module_symbol (module, symbol_name, symbol);
58         return res;
59 }
60
61 typedef struct MonoJniFunctions {
62         int (*MakeLocalRef) (JNIEnv *env, void *obj);
63         void * (*UnwrapRef) (JNIEnv *env, void *ref);
64         int (*MakeGlobalRef) (void *obj);
65         void (*DeleteRef) (JNIEnv *env, void *ref);
66         int (*GetFieldCookie) (void *klass, void *name, void *sig, gboolean is_static);
67         int (*GetMethodCookie) (void *klass, void *name, void *sig, gboolean is_static);
68         void (*SetFieldValue) (void *cookie, void *obj, void *val);
69         void * (*GetFieldValue) (void *cookie, void *obj);
70         void * (*GetClassFromObject) (void *obj);
71         jboolean (*ExceptionCheck) (JNIEnv *env);
72         void * (*GetPendingException) (JNIEnv *env);
73         void (*SetPendingException) (JNIEnv *env, void *obj);
74         void * (*InvokeMethod) (JNIEnv *env, void *cookie, void *obj, void *args, int virtual);
75         void * (*GetMethodArgList) (void *cookie);
76         void * (*FindClass) (void *name);
77         void * (*GetJniEnv) (void);
78         void * (*AllocObject) (void *klass);
79 } MonoJniFunctions;
80
81 static MonoJniFunctions jniFuncs;
82
83 void
84 mono_jni_jnienv_init (
85         void *makelocalref_func,
86         void *unwrap_func,
87         void *makeglobalref_func,
88         void *deleteref_func,
89         void *getfieldcookie_func,
90         void *getmethodcookie_func,
91         void *setfieldvalue_func,
92         void *getfieldvalue_func,
93         void *getclassfromobject_func,
94         void *exceptioncheck_func,
95         void *getpendingexception_func,
96         void *setpendingexception_func,
97         void *invokemethod_func,
98         void *getmethodarglist_func,
99         void *findclass_func,
100         void *getjnienv_func,
101         void *allocobject_func)
102 {
103         jniFuncs.MakeLocalRef = makelocalref_func;
104         jniFuncs.UnwrapRef = unwrap_func;
105         jniFuncs.MakeGlobalRef = makeglobalref_func;
106         jniFuncs.DeleteRef = deleteref_func;
107         jniFuncs.GetFieldCookie = getfieldcookie_func;
108         jniFuncs.GetMethodCookie = getmethodcookie_func;
109         jniFuncs.SetFieldValue = setfieldvalue_func;
110         jniFuncs.GetFieldValue = getfieldvalue_func;
111         jniFuncs.GetClassFromObject = getclassfromobject_func;
112         jniFuncs.ExceptionCheck = exceptioncheck_func;
113         jniFuncs.GetPendingException = getpendingexception_func;
114         jniFuncs.SetPendingException = setpendingexception_func;
115         jniFuncs.InvokeMethod = invokemethod_func;
116         jniFuncs.GetMethodArgList = getmethodarglist_func;
117         jniFuncs.FindClass = findclass_func;
118         jniFuncs.GetJniEnv = getjnienv_func;
119         jniFuncs.AllocObject = allocobject_func;
120 }
121
122 static void *jni_func_table[256];
123
124 static void ***jni_ptr = NULL;
125
126 static void *vm_func_table[64];
127
128 static void ***vm_ptr = NULL;
129
130 void*
131 mono_jni_get_func_table (void)
132 {
133         if (!jni_ptr) {
134                 jni_ptr = (void***)&jni_func_table;
135         }
136
137         return jni_ptr;
138 }
139
140 void
141 mono_jni_set_jnifunc (int index, void *func)
142 {
143         jni_func_table [index] = func;
144 }
145
146 static MonoString *
147 StringFromUTF8 (const char* psz)
148 {
149         /* TODO: */
150         return mono_string_new (mono_domain_get (), psz);
151 #if 0
152         /* Sun's modified UTF8 encoding is not compatible with System::Text::Encoding::UTF8, so */
153         /* we need to roll our own */
154         int len, res_len, i;
155         int *res;
156
157         len = strlen (psz);
158         res = g_malloc (len * sizeof (int));
159         res_len = 0;
160         for (i = 0; i < len; i++) {
161                 int c = (unsigned char)*psz++;
162                 int char2, char3;
163                 switch (c >> 4)
164                 {
165                 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
166                         /* 0xxxxxxx */
167                         break;
168                 case 12: case 13:
169                         /* 110x xxxx   10xx xxxx */
170                         char2 = *psz++;
171                         i++;
172                         c = (((c & 0x1F) << 6) | (char2 & 0x3F));
173                         break;
174                 case 14:
175                         /* 1110 xxxx  10xx xxxx  10xx xxxx */
176                         char2 = *psz++;
177                         char3 = *psz++;
178                         i++;
179                         i++;
180                         c = (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
181                         break;
182                 }
183
184                 res [res_len ++] = c;
185         }
186
187         return mono_string_new_utf16 (mono_domain_get (), res, res_len);
188 #endif
189 }
190
191 /***************************************************************************/
192 /*                        JNI FUNCTIONS                                    */
193 /***************************************************************************/
194
195
196 static jint JNICALL GetVersion (JNIEnv *env) { printf ("JNI Function GetVersion is not implemented.\n"); g_assert_not_reached (); return 0; }
197
198 static jclass JNICALL DefineClass (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len) { printf ("JNI Function DefineClass is not implemented.\n"); g_assert_not_reached (); return 0; }
199 static jclass JNICALL FindClass (JNIEnv *env, const char *name)
200 {
201         return (jclass)(jniFuncs.MakeLocalRef (env, jniFuncs.FindClass (StringFromUTF8(name))));
202 }
203
204 static jmethodID JNICALL FromReflectedMethod (JNIEnv *env, jobject method) { printf ("JNI Function FromReflectedMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
205 static jfieldID JNICALL FromReflectedField (JNIEnv *env, jobject field) { printf ("JNI Function FromReflectedField is not implemented.\n"); g_assert_not_reached (); return 0; }
206
207 static jobject JNICALL ToReflectedMethod (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic) { printf ("JNI Function ToReflectedMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
208
209 static jclass JNICALL GetSuperclass (JNIEnv *env, jclass sub) { printf ("JNI Function GetSuperclass is not implemented.\n"); g_assert_not_reached (); return 0; }
210 static jboolean JNICALL IsAssignableFrom (JNIEnv *env, jclass sub, jclass sup) { printf ("JNI Function IsAssignableFrom is not implemented.\n"); g_assert_not_reached (); return 0; }
211
212 static jobject JNICALL ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic) { printf ("JNI Function ToReflectedField is not implemented.\n"); g_assert_not_reached (); return 0; }
213
214 static jint JNICALL Throw (JNIEnv *env, jthrowable obj) { printf ("JNI Function Throw is not implemented.\n"); g_assert_not_reached (); return 0; }
215 static jint JNICALL ThrowNew (JNIEnv *env, jclass clazz, const char *msg) { printf ("JNI Function ThrowNew is not implemented.\n"); g_assert_not_reached (); return 0; }
216
217 static jthrowable JNICALL ExceptionOccurred (JNIEnv *env)
218 {
219         return (jthrowable)jniFuncs.MakeLocalRef (env, jniFuncs.GetPendingException (env));
220 }
221
222 static void JNICALL ExceptionDescribe (JNIEnv *env) { printf ("JNI Function ExceptionDescribe is not implemented.\n"); g_assert_not_reached (); }
223 static void JNICALL ExceptionClear (JNIEnv *env) { printf ("JNI Function ExceptionClear is not implemented.\n"); g_assert_not_reached (); }
224 static void JNICALL FatalError (JNIEnv *env, const char *msg) { printf ("JNI Function FatalError is not implemented.\n"); g_assert_not_reached (); }
225
226 static jint JNICALL PushLocalFrame (JNIEnv *env, jint capacity) { printf ("JNI Function PushLocalFrame is not implemented.\n"); g_assert_not_reached (); return 0; }
227 static jobject JNICALL PopLocalFrame (JNIEnv *env, jobject result) { printf ("JNI Function PopLocalFrame is not implemented.\n"); g_assert_not_reached (); return 0; }
228
229 static jobject JNICALL NewGlobalRef (JNIEnv *env, jobject lobj)
230 {
231         return (jobject)jniFuncs.MakeGlobalRef (jniFuncs.UnwrapRef (env, lobj));
232 }
233
234 static void JNICALL DeleteGlobalRef (JNIEnv *env, jobject gref)
235 {
236         jniFuncs.DeleteRef (env, gref);
237 }
238
239 static void JNICALL DeleteLocalRef (JNIEnv *env, jobject obj)
240 {
241         jniFuncs.DeleteRef (env, obj);
242 }
243
244 static jboolean JNICALL IsSameObject (JNIEnv *env, jobject obj1, jobject obj2) { printf ("JNI Function IsSameObject is not implemented.\n"); g_assert_not_reached (); return 0; }
245 static jobject JNICALL NewLocalRef (JNIEnv *env, jobject ref) { printf ("JNI Function NewLocalRef is not implemented.\n"); g_assert_not_reached (); return 0; }
246 static jint JNICALL EnsureLocalCapacity (JNIEnv *env, jint capacity) { printf ("JNI Function EnsureLocalCapacity is not implemented.\n"); g_assert_not_reached (); return 0; }
247
248 static jobject JNICALL AllocObject (JNIEnv *env, jclass clazz) { printf ("JNI Function EnsureLocalCapacity is not implemented.\n"); g_assert_not_reached (); return 0; }
249
250 static jclass JNICALL GetObjectClass (JNIEnv *env, jobject obj)
251 {
252         g_assert (obj);
253
254         return (jclass)jniFuncs.MakeLocalRef (env, jniFuncs.GetClassFromObject (jniFuncs.UnwrapRef (env, obj)));
255 }
256         
257 static jboolean JNICALL IsInstanceOf (JNIEnv *env, jobject obj, jclass clazz) { printf ("JNI Function IsInstanceOf is not implemented.\n"); g_assert_not_reached (); return 0; }
258
259 static jobject JNICALL CallObjectMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args) { printf ("JNI Function CallObjectMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
260
261 #define BOXED_VALUE(obj) ((char*)(obj) + sizeof (MonoObject))
262
263 static MonoObject *
264 box_Boolean (jboolean val)
265 {
266         return mono_value_box (mono_domain_get (), mono_get_boolean_class (), &val);
267 }
268
269 static MonoObject *
270 box_Byte (jbyte val)
271 {
272         /* Sbyte ! */
273         return mono_value_box (mono_domain_get (), mono_get_sbyte_class (), &val);
274 }
275
276 static MonoObject *
277 box_Char (jchar val)
278 {
279         return mono_value_box (mono_domain_get (), mono_get_char_class (), &val);
280 }
281
282 static MonoObject *
283 box_Short (jshort val)
284 {
285         return mono_value_box (mono_domain_get (), mono_get_int16_class (), &val);
286 }
287
288 static MonoObject *
289 box_Int (jint val)
290 {
291         return mono_value_box (mono_domain_get (), mono_get_int32_class (), &val);
292 }
293
294 static MonoObject *
295 box_Long (jlong val)
296 {
297         return mono_value_box (mono_domain_get (), mono_get_int64_class (), &val);
298 }
299
300 static MonoObject *
301 box_Float (jfloat val)
302 {
303         return mono_value_box (mono_domain_get (), mono_get_single_class (), &val);
304 }
305
306 static MonoObject *
307 box_Double (jdouble val)
308 {
309         return mono_value_box (mono_domain_get (), mono_get_double_class (), &val);
310 }
311
312 static int 
313 GetMethodArgs (jmethodID methodID, char* sig)
314 {
315         char *res;
316
317         res = jniFuncs.GetMethodArgList (methodID);
318         strcpy (sig, res);
319         return strlen (sig);
320 }
321
322 static MonoObject* 
323 InvokeHelper (JNIEnv *env, jobject object, jmethodID methodID, jvalue* args)
324 {
325         char sig[257];
326         int argc, i;
327         MonoObject **argarray;
328         MonoArray *args2;
329
330 /* assert(!pLocalRefs->PendingException); */
331         g_assert(methodID);
332
333         argc = GetMethodArgs(methodID, sig);
334         argarray = g_new (MonoObject*, argc);
335         for(i = 0; i < argc; i++)
336         {
337                 switch(sig[i])
338                 {
339                 case 'Z': {
340                         jboolean val = args[i].z != JNI_FALSE;
341                         argarray[i] = box_Boolean (val);
342                         break;
343                 }
344                 case 'B':
345                         argarray[i] = box_Byte (args[i].b);
346                         break;
347                 case 'C':
348                         argarray[i] = box_Char (args[i].c);
349                         break;
350                 case 'S':
351                         argarray[i] = box_Short (args[i].s);
352                         break;
353                 case 'I':
354                         argarray[i] = box_Int (args[i].i);
355                         break;
356                 case 'J':
357                         argarray[i] = box_Long (args[i].j);
358                         break;
359                 case 'F':
360                         argarray[i] = box_Float (args[i].f);
361                         break;
362                 case 'D':
363                         argarray[i] = box_Double (args[i].d);
364                         break;
365                 case 'L':
366                         argarray[i] = jniFuncs.UnwrapRef (env, args[i].l);
367                         break;
368                 }
369         }
370
371         args2 = mono_array_new (mono_domain_get (), mono_get_object_class (), argc);
372         for (i = 0; i < argc; ++i)
373                 mono_array_set (args2, MonoObject*, i, argarray [i]);
374
375         return jniFuncs.InvokeMethod (env, methodID, jniFuncs.UnwrapRef (env, object), args2, FALSE);
376 }
377
378 #define METHOD_IMPL_MANAGED(Type,type,cpptype) \
379 static type JNICALL Call##Type##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue* args)\
380 {\
381         MonoObject* ret = InvokeHelper(env, obj, methodID, args);\
382         if(ret) return *(type*)BOXED_VALUE(ret);\
383         return 0;\
384 }
385
386 #define METHOD_IMPL(Type,type) \
387 static type JNICALL Call##Type##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)\
388 {\
389         char sig[257];\
390     int i;\
391         int argc = GetMethodArgs(methodID, sig);\
392         jvalue* argarray = (jvalue*)alloca(argc * sizeof(jvalue));\
393         for(i = 0; i < argc; i++)\
394         {\
395                 switch(sig[i])\
396                 {\
397                 case 'Z':\
398                 case 'B':\
399                 case 'S':\
400                 case 'C':\
401                 case 'I':\
402                         argarray[i].i = va_arg(args, int);\
403                         break;\
404                 case 'J':\
405                         argarray[i].j = va_arg(args, gint64);\
406                         break;\
407                 case 'L':\
408                         argarray[i].l = va_arg(args, jobject);\
409                         break;\
410                 case 'D':\
411                         argarray[i].d = va_arg(args, double);\
412                         break;\
413                 case 'F':\
414                         argarray[i].f = (float)va_arg(args, double);\
415                         break;\
416                 }\
417         }\
418         return Call##Type##MethodA(env, obj, methodID, argarray);\
419 }\
420 static type Call##Type##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...) \
421 {\
422         va_list args;\
423     type ret;\
424         va_start(args, methodID);\
425         ret = Call##Type##MethodV(env, obj, methodID, args);\
426         va_end(args);\
427         return ret;\
428 }\
429 static type JNICALL CallNonvirtual##Type##Method (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) \
430 {\
431     printf ("JNI Function CallNonvirtual" #Type "Method is not implemented.\n"); g_assert_not_reached ();\
432     return 0;\
433 }\
434 static type JNICALL CallNonvirtual##Type##MethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args) \
435 {\
436     printf ("JNI Function CallNonvirtual" #Type "MethodV is not implemented.\n"); g_assert_not_reached ();\
437     return 0;\
438 }\
439 static type JNICALL CallNonvirtual##Type##MethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args) \
440 {\
441     printf ("JNI Function CallNonvirtual" #Type "MethodA is not implemented.\n"); g_assert_not_reached ();\
442     return 0;\
443 }
444
445 METHOD_IMPL_MANAGED(Boolean,jboolean,gboolean)
446 METHOD_IMPL_MANAGED(Byte,jbyte,gchar)
447 METHOD_IMPL_MANAGED(Char,jchar,gunichar2)
448 METHOD_IMPL_MANAGED(Short,jshort,gint16)
449 METHOD_IMPL_MANAGED(Int,jint,gint32)
450 METHOD_IMPL_MANAGED(Long,jlong,gint64)
451 METHOD_IMPL_MANAGED(Float,jfloat,float)
452 METHOD_IMPL_MANAGED(Double,jdouble,double)
453
454 METHOD_IMPL(Object,jobject)
455 METHOD_IMPL(Boolean,jboolean)
456 METHOD_IMPL(Byte,jbyte)
457 METHOD_IMPL(Char,jchar)
458 METHOD_IMPL(Short,jshort)
459 METHOD_IMPL(Int,jint)
460 METHOD_IMPL(Long,jlong)
461 METHOD_IMPL(Float,jfloat)
462 METHOD_IMPL(Double,jdouble)
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478 /* TODO: These should be put into the macros above...  */
479 static void JNICALL CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args) { 
480         InvokeHelper(env, obj, methodID, args);
481 }
482
483 static void JNICALL CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { 
484         char sig[257];
485         int argc, i;
486         jvalue* argarray;
487
488         argc = GetMethodArgs(methodID, sig);
489         argarray = (jvalue*)alloca(argc * sizeof(jvalue));
490
491         for(i = 0; i < argc; i++)
492         {
493                 switch(sig[i])
494                 {
495                 case 'Z':
496                 case 'B':
497                 case 'S':
498                 case 'C':
499                 case 'I':
500                         argarray[i].i = va_arg(args, int);
501                         break;
502                 case 'J':
503                         argarray[i].j = va_arg(args, gint64);
504                         break;
505                 case 'L':
506                         argarray[i].l = va_arg(args, jobject);
507                         break;
508                 case 'D':
509                         argarray[i].d = va_arg(args, double);
510                         break;
511                 case 'F':
512                         argarray[i].f = (float)va_arg(args, double);
513                         break;
514                 }
515         }
516         CallVoidMethodA(env, obj, methodID, argarray);
517 }
518
519 static void JNICALL CallVoidMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...) {
520         va_list args;
521         va_start(args, methodID);
522         CallVoidMethodV(env, obj, methodID, args);
523         va_end(args);
524 }
525
526 static void JNICALL CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallNonvirtualVoidMethod is not implemented.\n"); g_assert_not_reached (); }
527 static void JNICALL CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,       va_list args) { printf ("JNI Function CallNonvirtualVoidMethodV is not implemented.\n"); g_assert_not_reached (); }
528 static void JNICALL CallNonvirtualVoidMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,       jvalue * args) { printf ("JNI Function CallNonvirtualVoidMethodA is not implemented.\n"); g_assert_not_reached (); }
529
530 static jfieldID FindFieldID(JNIEnv *env, jclass cls, const char* name, const char* sig, gboolean isstatic)
531 {
532         return (jfieldID)jniFuncs.GetFieldCookie (jniFuncs.UnwrapRef (env, cls), StringFromUTF8 (name), StringFromUTF8 (sig), isstatic);
533 }
534
535 static jmethodID FindMethodID(JNIEnv *env, jclass cls, const char* name, const char* sig, gboolean isstatic)
536 {
537         return (jmethodID)jniFuncs.GetMethodCookie (
538                 jniFuncs.UnwrapRef (env, cls), StringFromUTF8(name), StringFromUTF8(sig), isstatic);
539 }
540
541 static jmethodID JNICALL GetMethodID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
542 {
543         return FindMethodID (env, clazz, name, sig, FALSE);
544 }
545
546
547 static jfieldID JNICALL GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
548 {
549         return FindFieldID (env, clazz, name, sig, FALSE);
550 }
551
552 static jfieldID JNICALL GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const char *sig) 
553 {       
554         return FindFieldID (env, clazz, name, sig, TRUE);
555 }
556
557 static jmethodID JNICALL GetStaticMethodID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
558 {
559         return FindMethodID (env, clazz, name, sig, TRUE);
560 }
561
562 #define GET_SET_FIELD(Type,type,cpptype) \
563 static void JNICALL Set##Type##Field(JNIEnv *env, jobject obj, jfieldID fieldID, type val)\
564 {\
565     jniFuncs.SetFieldValue (fieldID, jniFuncs.UnwrapRef (env, obj), \
566                             box_##Type (val));\
567 }\
568 static type JNICALL Get##Type##Field(JNIEnv *env, jobject obj, jfieldID fieldID)\
569 {\
570     return *(cpptype*)BOXED_VALUE(jniFuncs.GetFieldValue (fieldID, jniFuncs.UnwrapRef (env, obj)));\
571 }\
572 static void JNICALL SetStatic##Type##Field (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)\
573 {\
574     jniFuncs.SetFieldValue (fieldID, NULL, \
575                             box_##Type (value));\
576 }\
577 static type JNICALL GetStatic##Type##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)\
578 {\
579     return *(cpptype*)BOXED_VALUE(jniFuncs.GetFieldValue (fieldID, NULL));\
580 }\
581
582
583
584 /*    return *(cpptype*)BOXED_VALUE (jniFuncs.GetFieldValue (fieldID, jniFuncs.UnwrapRef (obj)));  */
585
586 GET_SET_FIELD(Boolean,jboolean,gboolean)
587 GET_SET_FIELD(Byte,jbyte, gchar)
588 GET_SET_FIELD(Char,jchar, gunichar2)
589 GET_SET_FIELD(Short,jshort,gshort)
590 GET_SET_FIELD(Int,jint,int)
591 GET_SET_FIELD(Long,jlong, gint64)
592 GET_SET_FIELD(Float,jfloat,float)
593 GET_SET_FIELD(Double,jdouble,double)
594
595 static jobject JNICALL GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
596 {
597         return (jobject)(jniFuncs.MakeLocalRef (env, jniFuncs.GetFieldValue (fieldID, jniFuncs.UnwrapRef (env, obj))));
598 }
599
600 static void JNICALL SetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val)
601 {
602         jniFuncs.SetFieldValue (fieldID, jniFuncs.UnwrapRef (env, obj), jniFuncs.UnwrapRef (env, val));
603 }
604
605 static jobject JNICALL GetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID)
606 {
607         return (jobject)(jniFuncs.MakeLocalRef (env, jniFuncs.GetFieldValue (fieldID, NULL)));
608 }       
609
610 static void JNICALL SetStaticObjectField (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
611 {
612         jniFuncs.SetFieldValue (fieldID, NULL, jniFuncs.UnwrapRef (env, value));
613 }       
614
615
616
617 static jobject JNICALL CallStaticObjectMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallStaticObjectMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
618 static jobject JNICALL CallStaticObjectMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticObjectMethodV is not implemented.\n"); g_assert_not_reached (); return 0; }
619 static jobject JNICALL CallStaticObjectMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { printf ("JNI Function CallStaticObjectMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
620
621 static jboolean JNICALL CallStaticBooleanMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallStaticBooleanMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
622 static jboolean JNICALL CallStaticBooleanMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticBooleanMethodV is not implemented.\n"); g_assert_not_reached (); return 0; }
623 static jboolean JNICALL CallStaticBooleanMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { printf ("JNI Function CallStaticBooleanMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
624
625 static jbyte JNICALL CallStaticByteMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallStaticByteMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
626 static jbyte JNICALL CallStaticByteMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticByteMethodV is not implemented.\n"); g_assert_not_reached (); return 0; }
627 static jbyte JNICALL CallStaticByteMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { printf ("JNI Function CallStaticByteMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
628
629 static jchar JNICALL CallStaticCharMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallStaticCharMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
630 static jchar JNICALL CallStaticCharMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticCharMethodV is not implemented.\n"); g_assert_not_reached (); return 0; }
631 static jchar JNICALL CallStaticCharMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { printf ("JNI Function CallStaticCharMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
632
633 static jshort JNICALL CallStaticShortMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallStaticShortMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
634 static jshort JNICALL CallStaticShortMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticShortMethodV is not implemented.\n"); g_assert_not_reached (); return 0; }
635 static jshort JNICALL CallStaticShortMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { printf ("JNI Function CallStaticShortMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
636
637 static jint JNICALL CallStaticIntMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallStaticIntMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
638 static jint JNICALL CallStaticIntMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticIntMethodV is not implemented.\n"); g_assert_not_reached (); return 0; }
639 static jint JNICALL CallStaticIntMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { printf ("JNI Function CallStaticIntMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
640
641 static jlong JNICALL CallStaticLongMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallStaticLongMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
642 static jlong JNICALL CallStaticLongMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticLongMethodV is not implemented.\n"); g_assert_not_reached (); return 0; }
643 static jlong JNICALL CallStaticLongMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { printf ("JNI Function CallStaticLongMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
644
645 static jfloat JNICALL CallStaticFloatMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallStaticFloatMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
646 static jfloat JNICALL CallStaticFloatMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticFloatMethodV is not implemented.\n"); g_assert_not_reached (); return 0; }
647 static jfloat JNICALL CallStaticFloatMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { printf ("JNI Function CallStaticFloatMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
648
649 static jdouble JNICALL CallStaticDoubleMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...) { printf ("JNI Function CallStaticDoubleMethod is not implemented.\n"); g_assert_not_reached (); return 0; }
650 static jdouble JNICALL CallStaticDoubleMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticDoubleMethodV is not implemented.\n"); g_assert_not_reached (); return 0; }
651 static jdouble JNICALL CallStaticDoubleMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { printf ("JNI Function CallStaticDoubleMethodA is not implemented.\n"); g_assert_not_reached (); return 0; }
652
653 static void JNICALL CallStaticVoidMethod (JNIEnv *env, jclass cls, jmethodID methodID, ...) { printf ("JNI Function CallStaticVoidMethod is not implemented.\n"); g_assert_not_reached (); }
654 static void JNICALL CallStaticVoidMethodV (JNIEnv *env, jclass cls, jmethodID methodID, va_list args) { printf ("JNI Function CallStaticVoidMethodV is not implemented.\n"); g_assert_not_reached (); }
655 static void JNICALL CallStaticVoidMethodA (JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args) { printf ("JNI Function CallStaticVoidMethodA is not implemented.\n"); g_assert_not_reached (); }
656
657 static jstring JNICALL NewString (JNIEnv *env, const jchar *unicode, jsize len) { printf ("JNI Function NewString is not implemented.\n"); g_assert_not_reached (); return 0; }
658 static jsize JNICALL GetStringLength (JNIEnv *env, jstring str) { printf ("JNI Function GetStringLength is not implemented.\n"); g_assert_not_reached (); return 0; }
659 static const jchar *JNICALL GetStringChars (JNIEnv *env, jstring str, jboolean *isCopy) { printf ("JNI Function GetStringChars is not implemented.\n"); g_assert_not_reached (); return 0; }
660 static void JNICALL ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars) { printf ("JNI Function ReleaseStringChars is not implemented.\n"); g_assert_not_reached (); }
661
662 static jstring JNICALL NewStringUTF (JNIEnv *env, const char *utf)
663 {
664         return (jstring)jniFuncs.MakeLocalRef (env, StringFromUTF8 (utf));
665 }
666
667 static jsize JNICALL GetStringUTFLength (JNIEnv *env, jstring str) { printf ("JNI Function GetStringUTFLength is not implemented.\n"); g_assert_not_reached (); return 0; }
668
669 static const char* JNICALL GetStringUTFChars (JNIEnv *env, jstring str, jboolean *isCopy)
670 {
671         MonoString *s;
672         char *buf;
673         int i, j, e;
674
675         s = jniFuncs.UnwrapRef (env, str);
676         buf = g_malloc (mono_string_length (s) * 3 + 1);
677
678         j = 0;
679         for(i = 0, e = mono_string_length (s); i < e; i++)
680         {
681                 jchar ch = mono_string_chars (s)[i];
682                 if ((ch != 0) && (ch <=0x7f))
683                 {
684                         buf[j++] = (char)ch;
685                 }
686                 else if (ch <= 0x7FF)
687                 {
688                         /* 11 bits or less. */
689                         unsigned char high_five = ch >> 6;
690                         unsigned char low_six = ch & 0x3F;
691                         buf[j++] = high_five | 0xC0; /* 110xxxxx */
692                         buf[j++] = low_six | 0x80;   /* 10xxxxxx */
693                 }
694                 else
695                 {
696                         /* possibly full 16 bits. */
697                         char high_four = ch >> 12;
698                         char mid_six = (ch >> 6) & 0x3F;
699                         char low_six = ch & 0x3f;
700                         buf[j++] = high_four | 0xE0; /* 1110xxxx */
701                         buf[j++] = mid_six | 0x80;   /* 10xxxxxx */
702                         buf[j++] = low_six | 0x80;   /* 10xxxxxx*/
703                 }
704         }
705         buf[j] = 0;
706         if(isCopy)
707         {
708                 *isCopy = JNI_TRUE;
709         }
710
711         return buf;
712 }
713         
714 static void JNICALL ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
715 {
716         g_free ((char*)chars);
717 }
718
719 static jsize JNICALL GetArrayLength (JNIEnv *env, jarray array)
720 {
721         MonoArray *arr = jniFuncs.UnwrapRef (env, array);
722         return mono_array_length (arr);
723 }
724
725 static jobject JNICALL GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index) { printf ("JNI Function GetObjectArrayElement is not implemented.\n"); g_assert_not_reached (); return 0; }
726 static void JNICALL SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index, jobject val) { printf ("JNI Function SetObjectArrayElement is not implemented.\n"); g_assert_not_reached (); }
727
728 static int new_java_array (JNIEnv *env, MonoClass *eclass, jsize len)
729 {
730         return jniFuncs.MakeLocalRef (env, mono_array_new (mono_domain_get (), eclass, len));
731 }       
732
733 static jobjectArray JNICALL NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init) { printf ("JNI Function NewObjectArray is not implemented.\n"); g_assert_not_reached (); return 0; }
734
735 static jbooleanArray JNICALL NewBooleanArray (JNIEnv *env, jsize len)
736 {
737         return (jbooleanArray)new_java_array (env, mono_get_boolean_class (), len);
738 }       
739
740 static jbyteArray JNICALL NewByteArray (JNIEnv *env, jsize len)
741 {
742         return (jbyteArray)new_java_array (env, mono_get_sbyte_class (), len);
743 }
744         
745 static jcharArray JNICALL NewCharArray (JNIEnv *env, jsize len)
746 {
747         return (jcharArray)new_java_array (env, mono_get_char_class (), len);
748 }
749         
750 static jshortArray JNICALL NewShortArray (JNIEnv *env, jsize len)
751 {
752         return (jshortArray)new_java_array (env, mono_get_int16_class (), len);
753 }       
754
755 static jintArray JNICALL NewIntArray (JNIEnv *env, jsize len)
756 {
757         return (jintArray)new_java_array (env, mono_get_int32_class (), len);
758 }
759
760 static jlongArray JNICALL NewLongArray (JNIEnv *env, jsize len)
761 {
762         return (jlongArray)new_java_array (env, mono_get_int64_class (), len);
763 }
764
765 static jfloatArray JNICALL NewFloatArray (JNIEnv *env, jsize len)
766 {
767         return (jfloatArray)new_java_array (env, mono_get_single_class (), len);
768 }
769
770 static jdoubleArray JNICALL NewDoubleArray (JNIEnv *env, jsize len)
771 {
772         return (jdoubleArray)new_java_array (env, mono_get_double_class (), len);
773 }
774
775 /* Original version with copy */
776 #if 0
777 #define GET_SET_ARRAY_ELEMENTS(Type,type,cpptype) \
778 static type* JNICALL Get##Type##ArrayElements(JNIEnv *env, type##Array array, jboolean *isCopy)\
779 {\
780         int i; \
781         MonoArray *obj; \
782     type *res; \
783 \
784         obj = jniFuncs.UnwrapRef ((void*)array); \
785         res = g_new (type, mono_array_length (obj) + 1); \
786         for (i = 0; i < mono_array_length (obj); ++i) { \
787                 res [i] = mono_array_get (obj, cpptype, i); \
788         } \
789 \
790         if (isCopy) \
791                 *isCopy = JNI_TRUE; \
792         return res; \
793 } \
794 \
795 static void JNICALL Release##Type##ArrayElements(JNIEnv *env, type##Array array, type *elems, jint mode)\
796 {\
797         int i; \
798         MonoArray *obj; \
799     type *res; \
800 \
801         obj = jniFuncs.UnwrapRef ((void*)array); \
802         if(mode == 0)\
803         {\
804             for (i = 0; i < mono_array_length (obj); ++i) \
805                     mono_array_get (obj, cpptype, i) = elems [i]; \
806         g_free (elems); \
807         }\
808         else if(mode == JNI_COMMIT)\
809         {\
810             for (i = 0; i < mono_array_length (obj); ++i) \
811                     mono_array_get (obj, cpptype, i) = elems [i]; \
812         }\
813         else if(mode == JNI_ABORT)\
814         {\
815         g_free (elems);\
816         }\
817 }
818 #endif
819
820
821 /*
822  * Fast version with no copy. Works because the mono garbage collector is
823  * non-copying.
824  */
825 #define GET_SET_ARRAY_ELEMENTS(Type,type,cpptype) \
826 static type* JNICALL Get##Type##ArrayElements(JNIEnv *env, type##Array array, jboolean *isCopy)\
827 {\
828         MonoArray *obj; \
829 \
830         obj = jniFuncs.UnwrapRef (env, (void*)array); \
831     if (isCopy) \
832       *isCopy = JNI_FALSE;\
833     return (type*)mono_array_addr (obj, cpptype, 0); \
834 } \
835 \
836 static void JNICALL Release##Type##ArrayElements(JNIEnv *env, type##Array array, type *elems, jint mode)\
837 {\
838     return; \
839 } \
840 static void JNICALL Get##Type##ArrayRegion (JNIEnv *env, type##Array array, jsize start, jsize l, type *buf) \
841 {\
842     MonoArray *obj; \
843         obj = jniFuncs.UnwrapRef (env, (void*)array); \
844     memcpy (buf, mono_array_addr (obj, sizeof (type), start), (sizeof (type) * l)); \
845 } \
846 static void JNICALL Set##Type##ArrayRegion (JNIEnv *env, type##Array array, jsize start, jsize l, type *buf) \
847 { \
848     MonoArray *obj; \
849         obj = jniFuncs.UnwrapRef (env, (void*)array); \
850     memcpy (mono_array_addr (obj, sizeof (type), start), buf, (sizeof (type) * l)); \
851 }
852
853 GET_SET_ARRAY_ELEMENTS(Boolean,jboolean,gboolean)
854 GET_SET_ARRAY_ELEMENTS(Byte,jbyte,gchar)
855 GET_SET_ARRAY_ELEMENTS(Char,jchar,gunichar2)
856 GET_SET_ARRAY_ELEMENTS(Short,jshort,short)
857 GET_SET_ARRAY_ELEMENTS(Int,jint,int)
858 GET_SET_ARRAY_ELEMENTS(Long,jlong,glong)
859 GET_SET_ARRAY_ELEMENTS(Float,jfloat,float)
860 GET_SET_ARRAY_ELEMENTS(Double,jdouble,double)
861
862 static void * JNICALL GetPrimitiveArrayCritical (JNIEnv *env, jarray array, jboolean *isCopy) {
863         MonoArray *obj;
864
865         obj = jniFuncs.UnwrapRef (env, (void*)array);
866     if (isCopy)
867       *isCopy = JNI_FALSE;
868     return mono_array_addr (obj, void*, 0);
869 }
870
871 static void JNICALL ReleasePrimitiveArrayCritical (JNIEnv *env, jarray array, void *carray, jint mode) {
872 }
873
874 static const jchar * JNICALL GetStringCritical (JNIEnv *env, jstring string, jboolean *isCopy) {
875         MonoString *obj;
876
877         obj = jniFuncs.UnwrapRef (env, (void*)string);
878
879         if (isCopy)
880                 *isCopy = JNI_FALSE;
881
882         return mono_string_chars (obj);
883 }
884
885 static void JNICALL ReleaseStringCritical (JNIEnv *env, jstring string, const jchar *cstring)
886 {
887 }
888
889 static jobject JNICALL NewObjectA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
890 {
891         return (jobject)jniFuncs.MakeLocalRef (env, InvokeHelper (env, NULL, methodID, args));
892 }
893
894 static jobject JNICALL NewObjectV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
895 {
896         char sig[257];
897         int i;
898         jvalue *argarray;
899         int argc;
900
901         argc = GetMethodArgs(methodID, sig);
902         argarray = (jvalue*)alloca(argc * sizeof(jvalue));
903         for(i = 0; i < argc; i++)
904         {
905                 switch(sig[i])
906                 {
907                 case 'Z':
908                 case 'B':
909                 case 'S':
910                 case 'C':
911                 case 'I':
912                         argarray[i].i = va_arg(args, int);
913                         break;
914                 case 'J':
915                         argarray[i].j = va_arg(args, gint64);
916                         break;
917                 case 'L':
918                         argarray[i].l = va_arg(args, jobject);
919                         break;
920                 case 'D':
921                         argarray[i].d = va_arg(args, double);
922                         break;
923                 case 'F':
924                         argarray[i].f = (float)va_arg(args, double);
925                         break;
926                 }
927         }
928
929         return NewObjectA (env, clazz, methodID, argarray);
930 }
931
932 static jobject JNICALL NewObject (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
933 {
934         va_list args;
935         jobject o;
936         va_start(args, methodID);
937         o = NewObjectV(env, clazz, methodID, args);
938         va_end(args);
939         return o;
940 }
941
942 static jint JNICALL RegisterNatives (JNIEnv *env, jclass clazz, const JNINativeMethod *methods,       jint nMethods) { printf ("JNI Function RegisterNatives is not implemented.\n"); g_assert_not_reached (); return 0; }
943 static jint JNICALL UnregisterNatives (JNIEnv *env, jclass clazz) { printf ("JNI Function UnregisterNatives is not implemented.\n"); g_assert_not_reached (); return 0; }
944
945 static jint JNICALL MonitorEnter (JNIEnv *env, jobject obj) { printf ("JNI Function MonitorEnter is not implemented.\n"); g_assert_not_reached (); return 0; }
946 static jint JNICALL MonitorExit (JNIEnv *env, jobject obj) { printf ("JNI Function MonitorExit is not implemented.\n"); g_assert_not_reached (); return 0; }
947
948 jint JNICALL GetJavaVM (JNIEnv *env, JavaVM **vm)
949 {
950         if (!vm_ptr)
951                 vm_ptr = (void***)&vm_func_table;
952
953         *vm = (JavaVM*)&vm_ptr;
954
955         return JNI_OK;
956 }
957
958 static void JNICALL GetStringRegion (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf) { printf ("JNI Function GetStringRegion is not implemented.\n"); g_assert_not_reached (); }
959 static void JNICALL GetStringUTFRegion (JNIEnv *env, jstring str, jsize start, jsize len, char *buf) { printf ("JNI Function GetStringUTFRegion is not implemented.\n"); g_assert_not_reached (); }
960
961 static jweak JNICALL NewWeakGlobalRef (JNIEnv *env, jobject obj) { printf ("JNI Function NewWeakGlobalRef is not implemented.\n"); g_assert_not_reached (); return 0; }
962 static void JNICALL DeleteWeakGlobalRef (JNIEnv *env, jweak ref) { printf ("JNI Function DeleteWeakGlobalRef is not implemented.\n"); g_assert_not_reached (); }
963
964 static jboolean JNICALL ExceptionCheck (JNIEnv *env) { 
965         return jniFuncs.ExceptionCheck (env);
966 }
967
968 static jobject JNICALL NewDirectByteBuffer (JNIEnv* env, void* address, jlong capacity) { printf ("JNI Function NewDirectByteBuffer is not implemented.\n"); g_assert_not_reached (); return 0; }
969 static void* JNICALL GetDirectBufferAddress (JNIEnv* env, jobject buf) { printf ("JNI Function GetDirectBufferAddress is not implemented.\n"); g_assert_not_reached (); return 0; }
970 static jlong JNICALL GetDirectBufferCapacity (JNIEnv* env, jobject buf) { printf ("JNI Function GetDirectBufferCapacity is not implemented.\n"); g_assert_not_reached (); return 0; }
971
972
973 /***************************************************************************/
974 /*                         VM FUNCTIONS                                    */
975 /***************************************************************************/
976
977 static jint DestroyJavaVM (void *vm)
978 {
979         g_assert_not_reached ();
980         return 0;
981 }
982
983 static jint AttachCurrentThread (void *vm, void **penv, void *args)
984 {
985         g_assert_not_reached ();
986         return 0;
987 }
988
989 static jint DetachCurrentThread (void *vm)
990 {
991         g_assert_not_reached ();
992         return 0;
993 }
994
995 static jint GetEnv (void *vm, void **penv, jint version)
996 {
997         void *env = jniFuncs.GetJniEnv ();
998         if (env) {
999                 *penv = env;
1000                 return JNI_OK;
1001         }
1002         else {
1003                 *penv = NULL;
1004                 return JNI_EDETACHED;
1005         }
1006 }
1007
1008 static jint AttachCurrentThreadAsDaemon (void *vm, void **penv, void *args)
1009 {
1010         g_assert_not_reached ();
1011         return 0;
1012 }
1013
1014
1015
1016 /*****************************************************************************/
1017
1018 static void *jni_func_table[256] = {
1019         NULL,
1020         NULL,
1021         NULL,
1022         NULL,
1023         (void*)&GetVersion,
1024         (void*)&DefineClass,
1025         (void*)&FindClass,
1026         (void*)&FromReflectedMethod,
1027         (void*)&FromReflectedField,
1028         (void*)&ToReflectedMethod,
1029         (void*)&GetSuperclass,
1030         (void*)&IsAssignableFrom,
1031         (void*)&ToReflectedField,
1032         (void*)&Throw,
1033         (void*)&ThrowNew,
1034         (void*)&ExceptionOccurred,
1035         (void*)&ExceptionDescribe,
1036         (void*)&ExceptionClear,
1037         (void*)&FatalError,
1038         (void*)&PushLocalFrame,
1039         (void*)&PopLocalFrame,
1040         (void*)&NewGlobalRef,
1041         (void*)&DeleteGlobalRef,
1042         (void*)&DeleteLocalRef,
1043         (void*)&IsSameObject,
1044         (void*)&NewLocalRef,
1045         (void*)&EnsureLocalCapacity,
1046         (void*)&AllocObject,
1047         (void*)&NewObject,
1048         (void*)&NewObjectV,
1049         (void*)&NewObjectA,
1050         (void*)&GetObjectClass,
1051         (void*)&IsInstanceOf,
1052         (void*)&GetMethodID,
1053         (void*)&CallObjectMethod,
1054         (void*)&CallObjectMethodV,
1055         (void*)&CallObjectMethodA,
1056         (void*)&CallBooleanMethod,
1057         (void*)&CallBooleanMethodV,
1058         (void*)&CallBooleanMethodA,
1059         (void*)&CallByteMethod,
1060         (void*)&CallByteMethodV,
1061         (void*)&CallByteMethodA,
1062         (void*)&CallCharMethod,
1063         (void*)&CallCharMethodV,
1064         (void*)&CallCharMethodA,
1065         (void*)&CallShortMethod,
1066         (void*)&CallShortMethodV,
1067         (void*)&CallShortMethodA,
1068         (void*)&CallIntMethod,
1069         (void*)&CallIntMethodV,
1070         (void*)&CallIntMethodA,
1071         (void*)&CallLongMethod,
1072         (void*)&CallLongMethodV,
1073         (void*)&CallLongMethodA,
1074         (void*)&CallFloatMethod,
1075         (void*)&CallFloatMethodV,
1076         (void*)&CallFloatMethodA,
1077         (void*)&CallDoubleMethod,
1078         (void*)&CallDoubleMethodV,
1079         (void*)&CallDoubleMethodA,
1080         (void*)&CallVoidMethod,
1081         (void*)&CallVoidMethodV,
1082         (void*)&CallVoidMethodA,
1083         (void*)&CallNonvirtualObjectMethod,
1084         (void*)&CallNonvirtualObjectMethodV,
1085         (void*)&CallNonvirtualObjectMethodA,
1086         (void*)&CallNonvirtualBooleanMethod,
1087         (void*)&CallNonvirtualBooleanMethodV,
1088         (void*)&CallNonvirtualBooleanMethodA,
1089         (void*)&CallNonvirtualByteMethod,
1090         (void*)&CallNonvirtualByteMethodV,
1091         (void*)&CallNonvirtualByteMethodA,
1092         (void*)&CallNonvirtualCharMethod,
1093         (void*)&CallNonvirtualCharMethodV,
1094         (void*)&CallNonvirtualCharMethodA,
1095         (void*)&CallNonvirtualShortMethod,
1096         (void*)&CallNonvirtualShortMethodV,
1097         (void*)&CallNonvirtualShortMethodA,
1098         (void*)&CallNonvirtualIntMethod,
1099         (void*)&CallNonvirtualIntMethodV,
1100         (void*)&CallNonvirtualIntMethodA,
1101         (void*)&CallNonvirtualLongMethod,
1102         (void*)&CallNonvirtualLongMethodV,
1103         (void*)&CallNonvirtualLongMethodA,
1104         (void*)&CallNonvirtualFloatMethod,
1105         (void*)&CallNonvirtualFloatMethodV,
1106         (void*)&CallNonvirtualFloatMethodA,
1107         (void*)&CallNonvirtualDoubleMethod,
1108         (void*)&CallNonvirtualDoubleMethodV,
1109         (void*)&CallNonvirtualDoubleMethodA,
1110         (void*)&CallNonvirtualVoidMethod,
1111         (void*)&CallNonvirtualVoidMethodV,
1112         (void*)&CallNonvirtualVoidMethodA,
1113         (void*)&GetFieldID,
1114         (void*)&GetObjectField,
1115         (void*)&GetBooleanField,
1116         (void*)&GetByteField,
1117         (void*)&GetCharField,
1118         (void*)&GetShortField,
1119         (void*)&GetIntField,
1120         (void*)&GetLongField,
1121         (void*)&GetFloatField,
1122         (void*)&GetDoubleField,
1123         (void*)&SetObjectField,
1124         (void*)&SetBooleanField,
1125         (void*)&SetByteField,
1126         (void*)&SetCharField,
1127         (void*)&SetShortField,
1128         (void*)&SetIntField,
1129         (void*)&SetLongField,
1130         (void*)&SetFloatField,
1131         (void*)&SetDoubleField,
1132         (void*)&GetStaticMethodID,
1133         (void*)&CallStaticObjectMethod,
1134         (void*)&CallStaticObjectMethodV,
1135         (void*)&CallStaticObjectMethodA,
1136         (void*)&CallStaticBooleanMethod,
1137         (void*)&CallStaticBooleanMethodV,
1138         (void*)&CallStaticBooleanMethodA,
1139         (void*)&CallStaticByteMethod,
1140         (void*)&CallStaticByteMethodV,
1141         (void*)&CallStaticByteMethodA,
1142         (void*)&CallStaticCharMethod,
1143         (void*)&CallStaticCharMethodV,
1144         (void*)&CallStaticCharMethodA,
1145         (void*)&CallStaticShortMethod,
1146         (void*)&CallStaticShortMethodV,
1147         (void*)&CallStaticShortMethodA,
1148         (void*)&CallStaticIntMethod,
1149         (void*)&CallStaticIntMethodV,
1150         (void*)&CallStaticIntMethodA,
1151         (void*)&CallStaticLongMethod,
1152         (void*)&CallStaticLongMethodV,
1153         (void*)&CallStaticLongMethodA,
1154         (void*)&CallStaticFloatMethod,
1155         (void*)&CallStaticFloatMethodV,
1156         (void*)&CallStaticFloatMethodA,
1157         (void*)&CallStaticDoubleMethod,
1158         (void*)&CallStaticDoubleMethodV,
1159         (void*)&CallStaticDoubleMethodA,
1160         (void*)&CallStaticVoidMethod,
1161         (void*)&CallStaticVoidMethodV,
1162         (void*)&CallStaticVoidMethodA,
1163         (void*)&GetStaticFieldID,
1164         (void*)&GetStaticObjectField,
1165         (void*)&GetStaticBooleanField,
1166         (void*)&GetStaticByteField,
1167         (void*)&GetStaticCharField,
1168         (void*)&GetStaticShortField,
1169         (void*)&GetStaticIntField,
1170         (void*)&GetStaticLongField,
1171         (void*)&GetStaticFloatField,
1172         (void*)&GetStaticDoubleField,
1173         (void*)&SetStaticObjectField,
1174         (void*)&SetStaticBooleanField,
1175         (void*)&SetStaticByteField,
1176         (void*)&SetStaticCharField,
1177         (void*)&SetStaticShortField,
1178         (void*)&SetStaticIntField,
1179         (void*)&SetStaticLongField,
1180         (void*)&SetStaticFloatField,
1181         (void*)&SetStaticDoubleField,
1182         (void*)&NewString,
1183         (void*)&GetStringLength,
1184         (void*)&GetStringChars,
1185         (void*)&ReleaseStringChars,
1186         (void*)&NewStringUTF,
1187         (void*)&GetStringUTFLength,
1188         (void*)&GetStringUTFChars,
1189         (void*)&ReleaseStringUTFChars,
1190         (void*)&GetArrayLength,
1191         (void*)&NewObjectArray,
1192         (void*)&GetObjectArrayElement,
1193         (void*)&SetObjectArrayElement,
1194         (void*)&NewBooleanArray,
1195         (void*)&NewByteArray,
1196         (void*)&NewCharArray,
1197         (void*)&NewShortArray,
1198         (void*)&NewIntArray,
1199         (void*)&NewLongArray,
1200         (void*)&NewFloatArray,
1201         (void*)&NewDoubleArray,
1202         (void*)&GetBooleanArrayElements,
1203         (void*)&GetByteArrayElements,
1204         (void*)&GetCharArrayElements,
1205         (void*)&GetShortArrayElements,
1206         (void*)&GetIntArrayElements,
1207         (void*)&GetLongArrayElements,
1208         (void*)&GetFloatArrayElements,
1209         (void*)&GetDoubleArrayElements,
1210         (void*)&ReleaseBooleanArrayElements,
1211         (void*)&ReleaseByteArrayElements,
1212         (void*)&ReleaseCharArrayElements,
1213         (void*)&ReleaseShortArrayElements,
1214         (void*)&ReleaseIntArrayElements,
1215         (void*)&ReleaseLongArrayElements,
1216         (void*)&ReleaseFloatArrayElements,
1217         (void*)&ReleaseDoubleArrayElements,
1218         (void*)&GetBooleanArrayRegion,
1219         (void*)&GetByteArrayRegion,
1220         (void*)&GetCharArrayRegion,
1221         (void*)&GetShortArrayRegion,
1222         (void*)&GetIntArrayRegion,
1223         (void*)&GetLongArrayRegion,
1224         (void*)&GetFloatArrayRegion,
1225         (void*)&GetDoubleArrayRegion,
1226         (void*)&SetBooleanArrayRegion,
1227         (void*)&SetByteArrayRegion,
1228         (void*)&SetCharArrayRegion,
1229         (void*)&SetShortArrayRegion,
1230         (void*)&SetIntArrayRegion,
1231         (void*)&SetLongArrayRegion,
1232         (void*)&SetFloatArrayRegion,
1233         (void*)&SetDoubleArrayRegion,
1234         (void*)&RegisterNatives,
1235         (void*)&UnregisterNatives,
1236         (void*)&MonitorEnter,
1237         (void*)&MonitorExit,
1238         (void*)&GetJavaVM,
1239         (void*)&GetStringRegion,
1240         (void*)&GetStringUTFRegion,
1241         (void*)&GetPrimitiveArrayCritical,
1242         (void*)&ReleasePrimitiveArrayCritical,
1243         (void*)&GetStringCritical,
1244         (void*)&ReleaseStringCritical,
1245         (void*)&NewWeakGlobalRef,
1246         (void*)&DeleteWeakGlobalRef,
1247         (void*)&ExceptionCheck,
1248         (void*)&NewDirectByteBuffer,
1249         (void*)&GetDirectBufferAddress,
1250         (void*)&GetDirectBufferCapacity
1251 };
1252
1253 static void *vm_func_table[64] = {
1254         NULL,
1255         NULL,
1256         NULL,
1257         (void*)&DestroyJavaVM,
1258         (void*)&AttachCurrentThread,
1259         (void*)&DetachCurrentThread,
1260         (void*)&GetEnv,
1261         (void*)&AttachCurrentThreadAsDaemon
1262 };
1263