53eaf0b89ff2e64beb6a52185fb9b14d6c4daa42
[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         }
283         env->DeleteLocalRef(cls);
284     }
285     return mid;
286 }
287
288
289 #define CALL_JNI_METHOD(function_type,obj,name,sig) \
290     va_list args;\
291     va_start (args, sig);\
292     \
293     jvalue result = callJNIMethod(function_type, obj, name, sig, args);\
294     \
295     va_end (args);
296
297 #define CALL_JNI_STATIC_METHOD(function_type,cls,name,sig) \
298     va_list args;\
299     va_start (args, sig);\
300     \
301     jvalue result = callJNIStaticMethod(function_type, cls, name, sig, args);\
302     \
303     va_end (args);
304
305 void KJS::Bindings::callJNIVoidMethod (jobject obj, const char *name, const char *sig, ... )
306 {
307     CALL_JNI_METHOD (void_type, obj, name, sig);
308 }
309
310 jobject KJS::Bindings::callJNIObjectMethod (jobject obj, const char *name, const char *sig, ... )
311 {
312     CALL_JNI_METHOD (object_type, obj, name, sig);
313     return result.l;
314 }
315
316 jboolean KJS::Bindings::callJNIBooleanMethod( jobject obj, const char *name, const char *sig, ... )
317 {
318     CALL_JNI_METHOD (boolean_type, obj, name, sig);
319     return result.z;
320 }
321
322 jboolean KJS::Bindings::callJNIStaticBooleanMethod (jclass cls, const char *name, const char *sig, ... )
323 {
324     CALL_JNI_STATIC_METHOD (boolean_type, cls, name, sig);
325     return result.z;
326 }
327
328 jbyte KJS::Bindings::callJNIByteMethod( jobject obj, const char *name, const char *sig, ... )
329 {
330     CALL_JNI_METHOD (byte_type, obj, name, sig);
331     return result.b;
332 }
333
334 jchar KJS::Bindings::callJNICharMethod (jobject obj, const char *name, const char *sig, ... )
335 {
336     CALL_JNI_METHOD (char_type, obj, name, sig);
337     return result.c;
338 }
339
340 jshort KJS::Bindings::callJNIShortMethod (jobject obj, const char *name, const char *sig, ... )
341 {
342     CALL_JNI_METHOD (short_type, obj, name, sig);
343     return result.s;
344 }
345
346 jint KJS::Bindings::callJNIIntMethod (jobject obj, const char *name, const char *sig, ... )
347 {
348     CALL_JNI_METHOD (int_type, obj, name, sig);
349     return result.i;
350 }
351
352 jlong KJS::Bindings::callJNILongMethod (jobject obj, const char *name, const char *sig, ... )
353 {
354     CALL_JNI_METHOD (long_type, obj, name, sig);
355     return result.j;
356 }
357
358 jfloat KJS::Bindings::callJNIFloatMethod (jobject obj, const char *name, const char *sig, ... )
359 {
360     CALL_JNI_METHOD (float_type, obj, name, sig);
361     return result.f;
362 }
363
364 jdouble KJS::Bindings::callJNIDoubleMethod (jobject obj, const char *name, const char *sig, ... )
365 {
366     CALL_JNI_METHOD (double_type, obj, name, sig);
367     return result.d;
368 }
369
370 void KJS::Bindings::callJNIVoidMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
371 {
372     jvalue result = callJNIMethodA (void_type, obj, name, sig, args);
373 }
374
375 jobject KJS::Bindings::callJNIObjectMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
376 {
377     jvalue result = callJNIMethodA (object_type, obj, name, sig, args);
378     return result.l;
379 }
380
381 jbyte KJS::Bindings::callJNIByteMethodA ( jobject obj, const char *name, const char *sig, jvalue *args)
382 {
383     jvalue result = callJNIMethodA (byte_type, obj, name, sig, args);
384     return result.b;
385 }
386
387 jchar KJS::Bindings::callJNICharMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
388 {
389     jvalue result = callJNIMethodA (char_type, obj, name, sig, args);
390     return result.c;
391 }
392
393 jshort KJS::Bindings::callJNIShortMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
394 {
395     jvalue result = callJNIMethodA (short_type, obj, name, sig, args);
396     return result.s;
397 }
398
399 jint KJS::Bindings::callJNIIntMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
400 {
401     jvalue result = callJNIMethodA (int_type, obj, name, sig, args);
402     return result.i;
403 }
404
405 jlong KJS::Bindings::callJNILongMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
406 {
407     jvalue result = callJNIMethodA (long_type, obj, name, sig, args);
408     return result.j;
409 }
410
411 jfloat KJS::Bindings::callJNIFloatMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
412 {
413     jvalue result = callJNIMethodA  (float_type, obj, name, sig, args);
414     return result.f;
415 }
416
417 jdouble KJS::Bindings::callJNIDoubleMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
418 {
419     jvalue result = callJNIMethodA (double_type, obj, name, sig, args);
420     return result.d;
421 }
422
423 jboolean KJS::Bindings::callJNIBooleanMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
424 {
425     jvalue result = callJNIMethodA (boolean_type, obj, name, sig, args);
426     return result.z;
427 }
428
429 void KJS::Bindings::callJNIVoidMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
430 {
431     jvalue result = callJNIMethodIDA (void_type, obj, methodID, args);
432 }
433
434 jobject KJS::Bindings::callJNIObjectMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
435 {
436     jvalue result = callJNIMethodIDA (object_type, obj, methodID, args);
437     return result.l;
438 }
439
440 jbyte KJS::Bindings::callJNIByteMethodIDA ( jobject obj, jmethodID methodID, jvalue *args)
441 {
442     jvalue result = callJNIMethodIDA (byte_type, obj, methodID, args);
443     return result.b;
444 }
445
446 jchar KJS::Bindings::callJNICharMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
447 {
448     jvalue result = callJNIMethodIDA (char_type, obj, methodID, args);
449     return result.c;
450 }
451
452 jshort KJS::Bindings::callJNIShortMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
453 {
454     jvalue result = callJNIMethodIDA (short_type, obj, methodID, args);
455     return result.s;
456 }
457
458 jint KJS::Bindings::callJNIIntMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
459 {
460     jvalue result = callJNIMethodIDA (int_type, obj, methodID, args);
461     return result.i;
462 }
463
464 jlong KJS::Bindings::callJNILongMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
465 {
466     jvalue result = callJNIMethodIDA (long_type, obj, methodID, args);
467     return result.j;
468 }
469
470 jfloat KJS::Bindings::callJNIFloatMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
471 {
472     jvalue result = callJNIMethodIDA  (float_type, obj, methodID, args);
473     return result.f;
474 }
475
476 jdouble KJS::Bindings::callJNIDoubleMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
477 {
478     jvalue result = callJNIMethodIDA (double_type, obj, methodID, args);
479     return result.d;
480 }
481
482 jboolean KJS::Bindings::callJNIBooleanMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
483 {
484     jvalue result = callJNIMethodIDA (boolean_type, obj, methodID, args);
485     return result.z;
486 }
487
488 const char *KJS::Bindings::getCharactersFromJString (jstring aJString)
489 {
490     return getCharactersFromJStringInEnv (getJNIEnv(), aJString);
491 }
492
493 void KJS::Bindings::releaseCharactersForJString (jstring aJString, const char *s)
494 {
495     releaseCharactersForJStringInEnv (getJNIEnv(), aJString, s);
496 }
497
498 const char *KJS::Bindings::getCharactersFromJStringInEnv (JNIEnv *env, jstring aJString)
499 {
500     jboolean isCopy;
501     const char *s = env->GetStringUTFChars((jstring)aJString, &isCopy);
502     if (!s) {
503         env->ExceptionDescribe();
504         env->ExceptionClear();
505                 fprintf (stderr, "\n");
506     }
507     return s;
508 }
509
510 void KJS::Bindings::releaseCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const char *s)
511 {
512     env->ReleaseStringUTFChars (aJString, s);
513 }
514
515 const jchar *KJS::Bindings::getUCharactersFromJStringInEnv (JNIEnv *env, jstring aJString)
516 {
517     jboolean isCopy;
518     const jchar *s = env->GetStringChars((jstring)aJString, &isCopy);
519     if (!s) {
520         env->ExceptionDescribe();
521         env->ExceptionClear();
522                 fprintf (stderr, "\n");
523     }
524     return s;
525 }
526
527 void KJS::Bindings::releaseUCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const jchar *s)
528 {
529     env->ReleaseStringChars (aJString, s);
530 }
531
532 JNIType KJS::Bindings::JNITypeFromClassName(const char *name)
533 {
534     JNIType type;
535     
536     if (strcmp("byte",name) == 0)
537         type = byte_type;
538     else if (strcmp("short",name) == 0)
539         type = short_type;
540     else if (strcmp("int",name) == 0)
541         type = int_type;
542     else if (strcmp("long",name) == 0)
543         type = long_type;
544     else if (strcmp("float",name) == 0)
545         type = float_type;
546     else if (strcmp("double",name) == 0)
547         type = double_type;
548     else if (strcmp("char",name) == 0)
549         type = char_type;
550     else if (strcmp("boolean",name) == 0)
551         type = boolean_type;
552     else if (strcmp("void",name) == 0)
553         type = void_type;
554     else
555         type = object_type;
556         
557     return type;
558 }
559
560 const char *KJS::Bindings::signatureFromPrimitiveType(JNIType type)
561 {
562     switch (type){
563         case void_type: 
564             return "V";
565         
566         case object_type:
567             return "L";
568         
569         case boolean_type:
570             return "Z";
571         
572         case byte_type:
573             return "B";
574             
575         case char_type:
576             return "C";
577         
578         case short_type:
579             return "S";
580         
581         case int_type:
582             return "I";
583         
584         case long_type:
585             return "J";
586         
587         case float_type:
588             return "F";
589         
590         case double_type:
591             return "D";
592
593         case invalid_type:
594         default:
595         break;
596     }
597     return "";
598 }
599
600 JNIType KJS::Bindings::JNITypeFromPrimitiveType(char type)
601 {
602     switch (type){
603         case 'V': 
604             return void_type;
605         
606         case 'L':
607         case '[':
608             return object_type;
609         
610         case 'Z':
611             return boolean_type;
612         
613         case 'B':
614             return byte_type;
615             
616         case 'C':
617             return char_type;
618         
619         case 'S':
620             return short_type;
621         
622         case 'I':
623             return int_type;
624         
625         case 'J':
626             return long_type;
627         
628         case 'F':
629             return float_type;
630         
631         case 'D':
632             return double_type;
633
634         default:
635         break;
636     }
637     return invalid_type;
638 }
639
640 jvalue KJS::Bindings::getJNIField( jobject obj, JNIType type, const char *name, const char *signature)
641 {
642     JavaVM *jvm = getJavaVM();
643     JNIEnv *env = getJNIEnv();
644     jvalue result;
645
646     bzero (&result, sizeof(jvalue));
647     if ( obj != NULL && jvm != NULL && env != NULL) {
648         jclass cls = env->GetObjectClass(obj);
649         if ( cls != NULL ) {
650             jfieldID field = env->GetFieldID(cls, name, signature);
651             if ( field != NULL ) {
652                 switch (type) {
653                 case object_type:
654                     result.l = env->functions->GetObjectField(env, obj, field);
655                     break;
656                 case boolean_type:
657                     result.z = env->functions->GetBooleanField(env, obj, field);
658                     break;
659                 case byte_type:
660                     result.b = env->functions->GetByteField(env, obj, field);
661                     break;
662                 case char_type:
663                     result.c = env->functions->GetCharField(env, obj, field);
664                     break;
665                 case short_type:
666                     result.s = env->functions->GetShortField(env, obj, field);
667                     break;
668                 case int_type:
669                     result.i = env->functions->GetIntField(env, obj, field);
670                     break;
671                 case long_type:
672                     result.j = env->functions->GetLongField(env, obj, field);
673                     break;
674                 case float_type:
675                     result.f = env->functions->GetFloatField(env, obj, field);
676                     break;
677                 case double_type:
678                     result.d = env->functions->GetDoubleField(env, obj, field);
679                     break;
680                 default:
681                     fprintf(stderr, "%s: invalid field type (%d)\n", __PRETTY_FUNCTION__, (int)type);
682                 }
683             }
684             else
685             {
686                 fprintf(stderr, "%s: Could not find field: %s\n", __PRETTY_FUNCTION__, name);
687                 env->ExceptionDescribe();
688                 env->ExceptionClear();
689                 fprintf (stderr, "\n");
690             }
691
692             env->DeleteLocalRef(cls);
693         }
694         else {
695             fprintf(stderr, "%s: Could not find class for object\n", __PRETTY_FUNCTION__);
696         }
697     }
698
699     return result;
700 }
701
702 jvalue KJS::Bindings::convertValueToJValue (KJS::ExecState *exec, KJS::Value value, JNIType _JNIType, const char *javaClassName)
703 {
704     jvalue result;
705    
706     switch (_JNIType){
707         case object_type: {
708             result.l = (jobject)0;
709             
710             // First see if we have a Java instance.
711             if (value.type() == KJS::ObjectType){
712                 KJS::ObjectImp *objectImp = static_cast<KJS::ObjectImp*>(value.imp());
713                 if (strcmp(objectImp->classInfo()->className, "RuntimeObject") == 0) {
714                     KJS::RuntimeObjectImp *imp = static_cast<KJS::RuntimeObjectImp *>(value.imp());
715                     JavaInstance *instance = static_cast<JavaInstance*>(imp->getInternalInstance());
716                     result.l = instance->javaInstance();
717                 }
718                 else if (strcmp(objectImp->classInfo()->className, "RuntimeArray") == 0) {
719                     KJS::RuntimeArrayImp *imp = static_cast<KJS::RuntimeArrayImp *>(value.imp());
720                     JavaArray *array = static_cast<JavaArray*>(imp->getConcreteArray());
721                     result.l = array->javaArray();
722                 }
723             }
724             
725             // Now convert value to a string if the target type is a java.lang.string, and we're not
726             // converting from a Null.
727             if (result.l == 0 && strcmp(javaClassName, "java.lang.String") == 0) {
728 #if CONVERT_NULL_TO_EMPTY_STRING
729                 if (value.type() == KJS::NullType) {
730                     JNIEnv *env = getJNIEnv();
731                     jchar buf[2];
732                     jobject javaString = env->functions->NewString (env, buf, 0);
733                     result.l = javaString;
734                 }
735                 else 
736 #else
737                 if (value.type() != KJS::NullType)
738 #endif
739                 {
740                     KJS::UString stringValue = value.toString(exec);
741                     JNIEnv *env = getJNIEnv();
742                     jobject javaString = env->functions->NewString (env, (const jchar *)stringValue.data(), stringValue.size());
743                     result.l = javaString;
744                 }
745             }
746         }
747         break;
748         
749         case boolean_type: {
750             result.z = (jboolean)value.toNumber(exec);
751         }
752         break;
753             
754         case byte_type: {
755             result.b = (jbyte)value.toNumber(exec);
756         }
757         break;
758         
759         case char_type: {
760             result.c = (jchar)value.toNumber(exec);
761         }
762         break;
763
764         case short_type: {
765             result.s = (jshort)value.toNumber(exec);
766         }
767         break;
768
769         case int_type: {
770             result.i = (jint)value.toNumber(exec);
771         }
772         break;
773
774         case long_type: {
775             result.j = (jlong)value.toNumber(exec);
776         }
777         break;
778
779         case float_type: {
780             result.f = (jfloat)value.toNumber(exec);
781         }
782         break;
783
784         case double_type: {
785             result.d = (jdouble)value.toNumber(exec);
786         }
787         break;
788             
789         break;
790
791         case invalid_type:
792         default:
793         case void_type: {
794             bzero (&result, sizeof(jvalue));
795         }
796         break;
797     }
798     return result;
799 }
800