Fixed <rdar://problem/3853676> Browser Crash when accessing CCWeb Progress Page...
[WebKit-https.git] / JavaScriptCore / bindings / jni / jni_utility.cpp
1 /*
2  * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25 #include <interpreter.h>
26 #include <list.h>
27
28 #include "jni_runtime.h"
29 #include "jni_utility.h"
30 #include "runtime_array.h"
31 #include "runtime_object.h"
32
33 using namespace KJS::Bindings;
34
35 static JavaVM *jvm = 0;
36
37 JavaVM *KJS::Bindings::getJavaVM()
38 {
39     if (jvm)
40         return jvm;
41
42     JavaVM *jvmArray[1];
43     jsize bufLen = 1;
44     jsize nJVMs = 0;
45     jint jniError = 0;
46
47     // Assumes JVM is already running ..., one per process
48     jniError = JNI_GetCreatedJavaVMs(jvmArray, bufLen, &nJVMs);
49     if ( jniError == JNI_OK && nJVMs > 0 ) {
50         jvm = jvmArray[0];
51     }
52     else 
53         fprintf(stderr, "%s: JNI_GetCreatedJavaVMs failed, returned %d\n", __PRETTY_FUNCTION__, jniError);
54         
55     return jvm;
56 }
57
58 JNIEnv *KJS::Bindings::getJNIEnv()
59 {
60     JNIEnv *env;
61     jint jniError = 0;
62
63     jniError = (getJavaVM())->AttachCurrentThread((void**)&env, (void *)NULL);
64     if ( jniError == JNI_OK )
65         return env;
66     else
67         fprintf(stderr, "%s: AttachCurrentThread failed, returned %d\n", __PRETTY_FUNCTION__, jniError);
68     return NULL;
69 }
70
71 static jvalue callJNIMethod (JNIType type, jobject obj, const char *name, const char *sig, va_list args)
72 {
73     JavaVM *jvm = getJavaVM();
74     JNIEnv *env = getJNIEnv();
75     jvalue result;
76
77     bzero (&result, sizeof(jvalue));
78     if ( obj != NULL && jvm != NULL && env != NULL) {
79         jclass cls = env->GetObjectClass(obj);
80         if ( cls != NULL ) {
81             jmethodID mid = env->GetMethodID(cls, name, sig);
82             if ( mid != NULL )
83             {
84                 switch (type) {
85                 case void_type:
86                     env->functions->CallVoidMethodV(env, obj, mid, args);
87                     break;
88                 case object_type:
89                     result.l = env->functions->CallObjectMethodV(env, obj, mid, args);
90                     break;
91                 case boolean_type:
92                     result.z = env->functions->CallBooleanMethodV(env, obj, mid, args);
93                     break;
94                 case byte_type:
95                     result.b = env->functions->CallByteMethodV(env, obj, mid, args);
96                     break;
97                 case char_type:
98                     result.c = env->functions->CallCharMethodV(env, obj, mid, args);
99                     break;
100                 case short_type:
101                     result.s = env->functions->CallShortMethodV(env, obj, mid, args);
102                     break;
103                 case int_type:
104                     result.i = env->functions->CallIntMethodV(env, obj, mid, args);
105                     break;
106                 case long_type:
107                     result.j = env->functions->CallLongMethodV(env, obj, mid, args);
108                     break;
109                 case float_type:
110                     result.f = env->functions->CallFloatMethodV(env, obj, mid, args);
111                     break;
112                 case double_type:
113                     result.d = env->functions->CallDoubleMethodV(env, obj, mid, args);
114                     break;
115                 default:
116                     fprintf(stderr, "%s: invalid function type (%d)\n", __PRETTY_FUNCTION__, (int)type);
117                 }
118             }
119             else
120             {
121                 fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, obj);
122                 env->ExceptionDescribe();
123                 env->ExceptionClear();
124                 fprintf (stderr, "\n");
125             }
126
127             env->DeleteLocalRef(cls);
128         }
129         else {
130             fprintf(stderr, "%s: Could not find class for %p\n", __PRETTY_FUNCTION__, obj);
131         }
132     }
133
134     return result;
135 }
136
137 static jvalue callJNIStaticMethod (JNIType type, jclass cls, const char *name, const char *sig, va_list args)
138 {
139     JavaVM *jvm = getJavaVM();
140     JNIEnv *env = getJNIEnv();
141     jvalue result;
142
143     bzero (&result, sizeof(jvalue));
144     if ( cls != NULL && jvm != NULL && env != NULL) {
145         jmethodID mid = env->GetStaticMethodID(cls, name, sig);
146         if ( mid != NULL )
147         {
148             switch (type) {
149             case void_type:
150                 env->functions->CallStaticVoidMethodV(env, cls, mid, args);
151                 break;
152             case object_type:
153                 result.l = env->functions->CallStaticObjectMethodV(env, cls, mid, args);
154                 break;
155             case boolean_type:
156                 result.z = env->functions->CallStaticBooleanMethodV(env, cls, mid, args);
157                 break;
158             case byte_type:
159                 result.b = env->functions->CallStaticByteMethodV(env, cls, mid, args);
160                 break;
161             case char_type:
162                 result.c = env->functions->CallStaticCharMethodV(env, cls, mid, args);
163                 break;
164             case short_type:
165                 result.s = env->functions->CallStaticShortMethodV(env, cls, mid, args);
166                 break;
167             case int_type:
168                 result.i = env->functions->CallStaticIntMethodV(env, cls, mid, args);
169                 break;
170             case long_type:
171                 result.j = env->functions->CallStaticLongMethodV(env, cls, mid, args);
172                 break;
173             case float_type:
174                 result.f = env->functions->CallStaticFloatMethodV(env, cls, mid, args);
175                 break;
176             case double_type:
177                 result.d = env->functions->CallStaticDoubleMethodV(env, cls, mid, args);
178                 break;
179             default:
180                 fprintf(stderr, "%s: invalid function type (%d)\n", __PRETTY_FUNCTION__, (int)type);
181             }
182         }
183         else
184         {
185             fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, cls);
186             env->ExceptionDescribe();
187             env->ExceptionClear();
188             fprintf (stderr, "\n");
189         }
190     }
191
192     return result;
193 }
194
195 static jvalue callJNIMethodIDA (JNIType type, jobject obj, jmethodID mid, jvalue *args)
196 {
197     JNIEnv *env = getJNIEnv();
198     jvalue result;
199     
200     bzero (&result, sizeof(jvalue));
201     if ( obj != NULL && mid != NULL )
202     {
203         switch (type) {
204         case void_type:
205             env->functions->CallVoidMethodA(env, obj, mid, args);
206             break;
207         case object_type:
208             result.l = env->functions->CallObjectMethodA(env, obj, mid, args);
209             break;
210         case boolean_type:
211             result.z = env->functions->CallBooleanMethodA(env, obj, mid, args);
212             break;
213         case byte_type:
214             result.b = env->functions->CallByteMethodA(env, obj, mid, args);
215             break;
216         case char_type:
217             result.c = env->functions->CallCharMethodA(env, obj, mid, args);
218             break;
219         case short_type:
220             result.s = env->functions->CallShortMethodA(env, obj, mid, args);
221             break;
222         case int_type:
223             result.i = env->functions->CallIntMethodA(env, obj, mid, args);
224             break;
225         case long_type:
226             result.j = env->functions->CallLongMethodA(env, obj, mid, args);
227             break;
228         case float_type:
229             result.f = env->functions->CallFloatMethodA(env, obj, mid, args);
230             break;
231         case double_type:
232             result.d = env->functions->CallDoubleMethodA(env, obj, mid, args);
233             break;
234         default:
235             fprintf(stderr, "%s: invalid function type (%d)\n", __PRETTY_FUNCTION__, (int)type);
236         }
237     }
238
239     return result;
240 }
241
242 static jvalue callJNIMethodA (JNIType type, jobject obj, const char *name, const char *sig, jvalue *args)
243 {
244     JavaVM *jvm = getJavaVM();
245     JNIEnv *env = getJNIEnv();
246     jvalue result;
247     
248     bzero (&result, sizeof(jvalue));
249     if ( obj != NULL && jvm != NULL && env != NULL) {
250         jclass cls = env->GetObjectClass(obj);
251         if ( cls != NULL ) {
252             jmethodID mid = env->GetMethodID(cls, name, sig);
253             if ( mid != NULL ) {
254                 result = callJNIMethodIDA (type, obj, mid, args);
255             }
256             else {
257                 fprintf(stderr, "%s: Could not find method: %s\n", __PRETTY_FUNCTION__, name);
258                 env->ExceptionDescribe();
259                 env->ExceptionClear();
260                 fprintf (stderr, "\n");
261             }
262
263             env->DeleteLocalRef(cls);
264         }
265         else {
266             fprintf(stderr, "%s: Could not find class for object\n", __PRETTY_FUNCTION__);
267         }
268     }
269
270     return result;
271 }
272
273 jmethodID KJS::Bindings::getMethodID (jobject obj, const char *name, const char *sig)
274 {
275     JNIEnv *env = getJNIEnv();
276     jmethodID mid = 0;
277         
278     if ( env != NULL) {
279     jclass cls = env->GetObjectClass(obj);
280     if ( cls != NULL ) {
281             mid = env->GetMethodID(cls, name, sig);
282             if (!mid) {
283                 env->ExceptionClear();
284                 mid = env->GetStaticMethodID(cls, name, sig);
285                 if (!mid) {
286                     env->ExceptionClear();
287                 }
288             }
289         }
290         env->DeleteLocalRef(cls);
291     }
292     return mid;
293 }
294
295
296 #define CALL_JNI_METHOD(function_type,obj,name,sig) \
297     va_list args;\
298     va_start (args, sig);\
299     \
300     jvalue result = callJNIMethod(function_type, obj, name, sig, args);\
301     \
302     va_end (args);
303
304 #define CALL_JNI_STATIC_METHOD(function_type,cls,name,sig) \
305     va_list args;\
306     va_start (args, sig);\
307     \
308     jvalue result = callJNIStaticMethod(function_type, cls, name, sig, args);\
309     \
310     va_end (args);
311
312 void KJS::Bindings::callJNIVoidMethod (jobject obj, const char *name, const char *sig, ... )
313 {
314     CALL_JNI_METHOD (void_type, obj, name, sig);
315 }
316
317 jobject KJS::Bindings::callJNIObjectMethod (jobject obj, const char *name, const char *sig, ... )
318 {
319     CALL_JNI_METHOD (object_type, obj, name, sig);
320     return result.l;
321 }
322
323 jboolean KJS::Bindings::callJNIBooleanMethod( jobject obj, const char *name, const char *sig, ... )
324 {
325     CALL_JNI_METHOD (boolean_type, obj, name, sig);
326     return result.z;
327 }
328
329 jboolean KJS::Bindings::callJNIStaticBooleanMethod (jclass cls, const char *name, const char *sig, ... )
330 {
331     CALL_JNI_STATIC_METHOD (boolean_type, cls, name, sig);
332     return result.z;
333 }
334
335 jbyte KJS::Bindings::callJNIByteMethod( jobject obj, const char *name, const char *sig, ... )
336 {
337     CALL_JNI_METHOD (byte_type, obj, name, sig);
338     return result.b;
339 }
340
341 jchar KJS::Bindings::callJNICharMethod (jobject obj, const char *name, const char *sig, ... )
342 {
343     CALL_JNI_METHOD (char_type, obj, name, sig);
344     return result.c;
345 }
346
347 jshort KJS::Bindings::callJNIShortMethod (jobject obj, const char *name, const char *sig, ... )
348 {
349     CALL_JNI_METHOD (short_type, obj, name, sig);
350     return result.s;
351 }
352
353 jint KJS::Bindings::callJNIIntMethod (jobject obj, const char *name, const char *sig, ... )
354 {
355     CALL_JNI_METHOD (int_type, obj, name, sig);
356     return result.i;
357 }
358
359 jlong KJS::Bindings::callJNILongMethod (jobject obj, const char *name, const char *sig, ... )
360 {
361     CALL_JNI_METHOD (long_type, obj, name, sig);
362     return result.j;
363 }
364
365 jfloat KJS::Bindings::callJNIFloatMethod (jobject obj, const char *name, const char *sig, ... )
366 {
367     CALL_JNI_METHOD (float_type, obj, name, sig);
368     return result.f;
369 }
370
371 jdouble KJS::Bindings::callJNIDoubleMethod (jobject obj, const char *name, const char *sig, ... )
372 {
373     CALL_JNI_METHOD (double_type, obj, name, sig);
374     return result.d;
375 }
376
377 void KJS::Bindings::callJNIVoidMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
378 {
379     jvalue result = callJNIMethodA (void_type, obj, name, sig, args);
380 }
381
382 jobject KJS::Bindings::callJNIObjectMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
383 {
384     jvalue result = callJNIMethodA (object_type, obj, name, sig, args);
385     return result.l;
386 }
387
388 jbyte KJS::Bindings::callJNIByteMethodA ( jobject obj, const char *name, const char *sig, jvalue *args)
389 {
390     jvalue result = callJNIMethodA (byte_type, obj, name, sig, args);
391     return result.b;
392 }
393
394 jchar KJS::Bindings::callJNICharMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
395 {
396     jvalue result = callJNIMethodA (char_type, obj, name, sig, args);
397     return result.c;
398 }
399
400 jshort KJS::Bindings::callJNIShortMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
401 {
402     jvalue result = callJNIMethodA (short_type, obj, name, sig, args);
403     return result.s;
404 }
405
406 jint KJS::Bindings::callJNIIntMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
407 {
408     jvalue result = callJNIMethodA (int_type, obj, name, sig, args);
409     return result.i;
410 }
411
412 jlong KJS::Bindings::callJNILongMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
413 {
414     jvalue result = callJNIMethodA (long_type, obj, name, sig, args);
415     return result.j;
416 }
417
418 jfloat KJS::Bindings::callJNIFloatMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
419 {
420     jvalue result = callJNIMethodA  (float_type, obj, name, sig, args);
421     return result.f;
422 }
423
424 jdouble KJS::Bindings::callJNIDoubleMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
425 {
426     jvalue result = callJNIMethodA (double_type, obj, name, sig, args);
427     return result.d;
428 }
429
430 jboolean KJS::Bindings::callJNIBooleanMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
431 {
432     jvalue result = callJNIMethodA (boolean_type, obj, name, sig, args);
433     return result.z;
434 }
435
436 void KJS::Bindings::callJNIVoidMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
437 {
438     jvalue result = callJNIMethodIDA (void_type, obj, methodID, args);
439 }
440
441 jobject KJS::Bindings::callJNIObjectMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
442 {
443     jvalue result = callJNIMethodIDA (object_type, obj, methodID, args);
444     return result.l;
445 }
446
447 jbyte KJS::Bindings::callJNIByteMethodIDA ( jobject obj, jmethodID methodID, jvalue *args)
448 {
449     jvalue result = callJNIMethodIDA (byte_type, obj, methodID, args);
450     return result.b;
451 }
452
453 jchar KJS::Bindings::callJNICharMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
454 {
455     jvalue result = callJNIMethodIDA (char_type, obj, methodID, args);
456     return result.c;
457 }
458
459 jshort KJS::Bindings::callJNIShortMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
460 {
461     jvalue result = callJNIMethodIDA (short_type, obj, methodID, args);
462     return result.s;
463 }
464
465 jint KJS::Bindings::callJNIIntMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
466 {
467     jvalue result = callJNIMethodIDA (int_type, obj, methodID, args);
468     return result.i;
469 }
470
471 jlong KJS::Bindings::callJNILongMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
472 {
473     jvalue result = callJNIMethodIDA (long_type, obj, methodID, args);
474     return result.j;
475 }
476
477 jfloat KJS::Bindings::callJNIFloatMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
478 {
479     jvalue result = callJNIMethodIDA  (float_type, obj, methodID, args);
480     return result.f;
481 }
482
483 jdouble KJS::Bindings::callJNIDoubleMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
484 {
485     jvalue result = callJNIMethodIDA (double_type, obj, methodID, args);
486     return result.d;
487 }
488
489 jboolean KJS::Bindings::callJNIBooleanMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
490 {
491     jvalue result = callJNIMethodIDA (boolean_type, obj, methodID, args);
492     return result.z;
493 }
494
495 const char *KJS::Bindings::getCharactersFromJString (jstring aJString)
496 {
497     return getCharactersFromJStringInEnv (getJNIEnv(), aJString);
498 }
499
500 void KJS::Bindings::releaseCharactersForJString (jstring aJString, const char *s)
501 {
502     releaseCharactersForJStringInEnv (getJNIEnv(), aJString, s);
503 }
504
505 const char *KJS::Bindings::getCharactersFromJStringInEnv (JNIEnv *env, jstring aJString)
506 {
507     jboolean isCopy;
508     const char *s = env->GetStringUTFChars((jstring)aJString, &isCopy);
509     if (!s) {
510         env->ExceptionDescribe();
511         env->ExceptionClear();
512                 fprintf (stderr, "\n");
513     }
514     return s;
515 }
516
517 void KJS::Bindings::releaseCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const char *s)
518 {
519     env->ReleaseStringUTFChars (aJString, s);
520 }
521
522 const jchar *KJS::Bindings::getUCharactersFromJStringInEnv (JNIEnv *env, jstring aJString)
523 {
524     jboolean isCopy;
525     const jchar *s = env->GetStringChars((jstring)aJString, &isCopy);
526     if (!s) {
527         env->ExceptionDescribe();
528         env->ExceptionClear();
529                 fprintf (stderr, "\n");
530     }
531     return s;
532 }
533
534 void KJS::Bindings::releaseUCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const jchar *s)
535 {
536     env->ReleaseStringChars (aJString, s);
537 }
538
539 JNIType KJS::Bindings::JNITypeFromClassName(const char *name)
540 {
541     JNIType type;
542     
543     if (strcmp("byte",name) == 0)
544         type = byte_type;
545     else if (strcmp("short",name) == 0)
546         type = short_type;
547     else if (strcmp("int",name) == 0)
548         type = int_type;
549     else if (strcmp("long",name) == 0)
550         type = long_type;
551     else if (strcmp("float",name) == 0)
552         type = float_type;
553     else if (strcmp("double",name) == 0)
554         type = double_type;
555     else if (strcmp("char",name) == 0)
556         type = char_type;
557     else if (strcmp("boolean",name) == 0)
558         type = boolean_type;
559     else if (strcmp("void",name) == 0)
560         type = void_type;
561     else
562         type = object_type;
563         
564     return type;
565 }
566
567 const char *KJS::Bindings::signatureFromPrimitiveType(JNIType type)
568 {
569     switch (type){
570         case void_type: 
571             return "V";
572         
573         case object_type:
574             return "L";
575         
576         case boolean_type:
577             return "Z";
578         
579         case byte_type:
580             return "B";
581             
582         case char_type:
583             return "C";
584         
585         case short_type:
586             return "S";
587         
588         case int_type:
589             return "I";
590         
591         case long_type:
592             return "J";
593         
594         case float_type:
595             return "F";
596         
597         case double_type:
598             return "D";
599
600         case invalid_type:
601         default:
602         break;
603     }
604     return "";
605 }
606
607 JNIType KJS::Bindings::JNITypeFromPrimitiveType(char type)
608 {
609     switch (type){
610         case 'V': 
611             return void_type;
612         
613         case 'L':
614         case '[':
615             return object_type;
616         
617         case 'Z':
618             return boolean_type;
619         
620         case 'B':
621             return byte_type;
622             
623         case 'C':
624             return char_type;
625         
626         case 'S':
627             return short_type;
628         
629         case 'I':
630             return int_type;
631         
632         case 'J':
633             return long_type;
634         
635         case 'F':
636             return float_type;
637         
638         case 'D':
639             return double_type;
640
641         default:
642         break;
643     }
644     return invalid_type;
645 }
646
647 jvalue KJS::Bindings::getJNIField( jobject obj, JNIType type, const char *name, const char *signature)
648 {
649     JavaVM *jvm = getJavaVM();
650     JNIEnv *env = getJNIEnv();
651     jvalue result;
652
653     bzero (&result, sizeof(jvalue));
654     if ( obj != NULL && jvm != NULL && env != NULL) {
655         jclass cls = env->GetObjectClass(obj);
656         if ( cls != NULL ) {
657             jfieldID field = env->GetFieldID(cls, name, signature);
658             if ( field != NULL ) {
659                 switch (type) {
660                 case object_type:
661                     result.l = env->functions->GetObjectField(env, obj, field);
662                     break;
663                 case boolean_type:
664                     result.z = env->functions->GetBooleanField(env, obj, field);
665                     break;
666                 case byte_type:
667                     result.b = env->functions->GetByteField(env, obj, field);
668                     break;
669                 case char_type:
670                     result.c = env->functions->GetCharField(env, obj, field);
671                     break;
672                 case short_type:
673                     result.s = env->functions->GetShortField(env, obj, field);
674                     break;
675                 case int_type:
676                     result.i = env->functions->GetIntField(env, obj, field);
677                     break;
678                 case long_type:
679                     result.j = env->functions->GetLongField(env, obj, field);
680                     break;
681                 case float_type:
682                     result.f = env->functions->GetFloatField(env, obj, field);
683                     break;
684                 case double_type:
685                     result.d = env->functions->GetDoubleField(env, obj, field);
686                     break;
687                 default:
688                     fprintf(stderr, "%s: invalid field type (%d)\n", __PRETTY_FUNCTION__, (int)type);
689                 }
690             }
691             else
692             {
693                 fprintf(stderr, "%s: Could not find field: %s\n", __PRETTY_FUNCTION__, name);
694                 env->ExceptionDescribe();
695                 env->ExceptionClear();
696                 fprintf (stderr, "\n");
697             }
698
699             env->DeleteLocalRef(cls);
700         }
701         else {
702             fprintf(stderr, "%s: Could not find class for object\n", __PRETTY_FUNCTION__);
703         }
704     }
705
706     return result;
707 }
708
709 jvalue KJS::Bindings::convertValueToJValue (KJS::ExecState *exec, KJS::Value value, JNIType _JNIType, const char *javaClassName)
710 {
711     jvalue result;
712    
713     switch (_JNIType){
714         case object_type: {
715             result.l = (jobject)0;
716             
717             // First see if we have a Java instance.
718             if (value.type() == KJS::ObjectType){
719                 KJS::ObjectImp *objectImp = static_cast<KJS::ObjectImp*>(value.imp());
720                 if (objectImp->classInfo() == &KJS::RuntimeObjectImp::info) {
721                     KJS::RuntimeObjectImp *imp = static_cast<KJS::RuntimeObjectImp *>(value.imp());
722                     JavaInstance *instance = static_cast<JavaInstance*>(imp->getInternalInstance());
723                     result.l = instance->javaInstance();
724                 }
725                 else if (objectImp->classInfo() == &KJS::RuntimeArrayImp::info) {
726                     KJS::RuntimeArrayImp *imp = static_cast<KJS::RuntimeArrayImp *>(value.imp());
727                     JavaArray *array = static_cast<JavaArray*>(imp->getConcreteArray());
728                     result.l = array->javaArray();
729                 }
730             }
731             
732             // Now convert value to a string if the target type is a java.lang.string, and we're not
733             // converting from a Null.
734             if (result.l == 0 && strcmp(javaClassName, "java.lang.String") == 0) {
735 #if CONVERT_NULL_TO_EMPTY_STRING
736                 if (value.type() == KJS::NullType) {
737                     JNIEnv *env = getJNIEnv();
738                     jchar buf[2];
739                     jobject javaString = env->functions->NewString (env, buf, 0);
740                     result.l = javaString;
741                 }
742                 else 
743 #else
744                 if (value.type() != KJS::NullType)
745 #endif
746                 {
747                     KJS::UString stringValue = value.toString(exec);
748                     JNIEnv *env = getJNIEnv();
749                     jobject javaString = env->functions->NewString (env, (const jchar *)stringValue.data(), stringValue.size());
750                     result.l = javaString;
751                 }
752             }
753         }
754         break;
755         
756         case boolean_type: {
757             result.z = (jboolean)value.toNumber(exec);
758         }
759         break;
760             
761         case byte_type: {
762             result.b = (jbyte)value.toNumber(exec);
763         }
764         break;
765         
766         case char_type: {
767             result.c = (jchar)value.toNumber(exec);
768         }
769         break;
770
771         case short_type: {
772             result.s = (jshort)value.toNumber(exec);
773         }
774         break;
775
776         case int_type: {
777             result.i = (jint)value.toNumber(exec);
778         }
779         break;
780
781         case long_type: {
782             result.j = (jlong)value.toNumber(exec);
783         }
784         break;
785
786         case float_type: {
787             result.f = (jfloat)value.toNumber(exec);
788         }
789         break;
790
791         case double_type: {
792             result.d = (jdouble)value.toNumber(exec);
793         }
794         break;
795             
796         break;
797
798         case invalid_type:
799         default:
800         case void_type: {
801             bzero (&result, sizeof(jvalue));
802         }
803         break;
804     }
805     return result;
806 }
807